dnl -*- mode: shell-script -*-
dnl Process this file with autoconf to produce a configure script.
dnl
dnl Permission is hereby granted, free of charge, to any person obtaining a
dnl copy of this software and associated documentation files (the "Software"),
dnl to deal in the Software without restriction, subject to the conditions
dnl listed in the Click LICENSE file. These conditions include: you must
dnl preserve this copyright notice, and you cannot mention the copyright
dnl holders in advertising related to the Software without their permission.
dnl The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
dnl notice is a summary of the Click LICENSE file; the license in that file is
dnl legally binding.

AC_INIT([click], [2.1])
AC_PREREQ(2.60)
AC_CONFIG_HEADERS([include/click/config.h:config.h.in], [echo > stamp-h])
AC_CONFIG_HEADERS([include/click/pathvars.h:pathvars.h.in])
AC_CONFIG_HEADERS([include/click/config-bsdmodule.h:config-bsdmodule.h.in include/click/config-linuxmodule.h:config-linuxmodule.h.in include/click/config-ns.h:config-ns.h.in include/click/config-userlevel.h:config-userlevel.h.in include/click/config-minios.h:config-minios.h.in])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([bin/click-buildtool:click-buildtool.in], [chmod +x bin/click-buildtool])
AC_CONFIG_FILES([bin/click-compile:click-compile.in], [chmod +x bin/click-compile])
AC_CONFIG_FILES([installch], [chmod +x installch])
AC_CONFIG_FILES([share/click/config.mk:config.mk.in share/click/pkg-config.mk])
AC_CONFIG_FILES([doc/Makefile etc/libclick/Makefile tools/Makefile tools/lib/Makefile])
AC_CONFIG_SRCDIR([click-buildtool.in])
ac_user_cxx=${CXX+y}

CLICK_VERSION=$PACKAGE_VERSION
dnl NB a real tab character!
tabchar='	'

AC_SUBST(ac_configure_args)
AC_DEFINE_UNQUOTED([CLICK_VERSION], ["$CLICK_VERSION"])
AC_SUBST(CLICK_VERSION)

click_version_code_in=`echo "$CLICK_VERSION" | sed -e 's/[[a-z]].*//' | sed -e 's/$/.0/' | tr . , | sed -e 's/^\([[0-9]]*,[[0-9]]*,[[0-9]]\).*/\1/'`
AC_DEFINE_UNQUOTED([CLICK_VERSION_CODE], [CLICK_MAKE_VERSION_CODE($click_version_code_in)])

CLICK_INIT('$(top_srcdir)')

dnl support for cross compiling
AC_CANONICAL_SYSTEM

dnl This is wrong!!
AC_CHECK_TOOL(CC, gcc)
AC_CHECK_TOOL(CXX, g++)

CLICK_PROG_CC
AC_PROG_CPP
AC_C_INLINE

CLICK_PROG_CXX
AC_PROG_CXXCPP

AX_CHECK_COMPILE_FLAG(-Winconsistent-missing-override,CXXFLAGS="$CXXFLAGS -Wno-inconsistent-missing-override",:,[-Werror])

AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <new>

int main() {
    std::size_t sz = 8;
    std::align_val_t al{64};
    void* a = operator new(sz,al);
    return (a == nullptr?1:0);
}]])],[AC_DEFINE(HAVE_ALIGNED_NEW)],[],[])

CLICK_PROG_KERNEL_CC
CLICK_PROG_KERNEL_CXX

ac_preset_ar="$AR"
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(LD, ld)
AC_CHECK_TOOL(NM, nm)
AC_CHECK_TOOL(OBJCOPY, objcopy)
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_CHECK_TOOL(READELF, readelf, :)
AC_CHECK_TOOL(STRIP, strip, :)

conf_auxdir='$(top_srcdir)'
AC_SUBST(conf_auxdir)

test -z "$AR_CREATEFLAGS" && AR_CREATEFLAGS=cru
AC_SUBST(AR_CREATEFLAGS)

EXTRA_DRIVER_OBJS=
EXTRA_TOOL_OBJS=
INCLUDES_LLVM=
LLVM_OBJS=
LIBS_LLVM=

dnl
dnl drivers
dnl

dnl userlevel driver and features

AC_ARG_ENABLE([userlevel],
    [AS_HELP_STRING([--disable-userlevel], [disable user-level driver])],
    [:], [enable_userlevel=yes])

AC_ARG_ENABLE([user-multithread],
    [AS_HELP_STRING([  --enable-user-multithread], [support userlevel multithreading])],
    [:], [enable_user_multithread=yes])

AC_ARG_ENABLE([fullpush-nonatomic],
    [AS_HELP_STRING([  --disable-fullpush-nonatomic], [disable nonatomic access to packet when single-threaded fullpush context is detected])],
    [:], [enable_fullpush_nonatomic=yes])

if test "x$enable_fullpush_nonatomic" = "xyes"; then
    AC_DEFINE([HAVE_FULLPUSH_NONATOMIC])
fi


AC_ARG_ENABLE([batch],
    [AS_HELP_STRING([  --disable-batch], [disable batching support])],
    [:], [enable_batch=$enable_userlevel])

if test "x$enable_batch" = "xyes"; then
    if test "x$enable_userlevel" != "xyes"; then
        AC_MSG_ERROR([
=========================================

--enable-batch requires --enable-userlevel which was not provided.

=========================================])
    fi
    AC_DEFINE([HAVE_BATCH])
    AC_SUBST(HAVE_BATCH, yes)
fi

AC_ARG_ENABLE([verbose-batch],
    [AS_HELP_STRING([  --disable-verbose-batch], [disable warnings and information about batching])],
    [:], [enable_verbose_batch=yes])

if test "x$enable_verbose_batch" = "xyes"; then
    AC_DEFINE([HAVE_VERBOSE_BATCH])
fi

AC_ARG_ENABLE([auto-batch],
    [AS_HELP_STRING([  --enable-auto-batch=[[list|jump|port]]], [make vanilla elements batch-compatible automatically])],
    [:], [enable_auto_batch=no])


if test "x$enable_auto_batch" = "xno" ; then
    :
elif test "x$enable_auto_batch" = "xyes" -o "x$enable_auto_batch" = "xport"; then
    AC_DEFINE([HAVE_AUTO_BATCH],[AUTO_BATCH_PORT], [Define if make vanilla elements batch-compatible automatically])
elif test "x$enable_auto_batch" = "xlist"; then
    AC_DEFINE([HAVE_AUTO_BATCH],[AUTO_BATCH_LIST], [Define if make vanilla elements batch-compatible automatically])
elif test "x$enable_auto_batch" = "xjump"; then
    AC_DEFINE([HAVE_AUTO_BATCH],[AUTO_BATCH_JUMP], [Define if make vanilla elements batch-compatible automatically])
else
        AC_MSG_ERROR([
=========================================

--enable-auto-batch only accepts jump, list or port as modes

=========================================])
fi

AC_ARG_ENABLE([netmap-pool],
    [AS_HELP_STRING([  --enable-netmap-pool], [use netmap buffers instead of standard Click buffers])],
    [:], [enable_netmap_pool=no])

PTHREAD_LIBS=""
AC_SUBST(PTHREAD_LIBS)

if test "x$enable_user_multithread" = xyes; then
    SAVE_LIBS="$LIBS"
    AC_SEARCH_LIBS([pthread_create], [pthread], [ac_have_libpthread=yes], [ac_have_libpthread=no])
    AC_CHECK_HEADERS([pthread.h], [ac_have_pthread_h=yes], [ac_have_pthread_h=no])
    if test "$ac_have_libpthread$ac_have_pthread_h" = yesyes; then
        AC_DEFINE([HAVE_USER_MULTITHREAD])
        AC_CHECK_DECLS([pthread_setaffinity_np], [], [], [#define _GNU_SOURCE
#include <pthread.h>])
        if echo "$LIBS" | grep -e -lpthread >/dev/null 2>&1; then
            PTHREAD_LIBS="-lpthread"
        fi
    else
        AC_MSG_ERROR([
=========================================

Can't find -lpthread and/or <pthread.h>, so I can't compile with
--enable-user-multithread.

=========================================])
    fi
    LIBS="$SAVE_LIBS"
fi

save_cpp="$CPPFLAGS"
save_libs="$LIBS"
CPPFLAGS="$CPPFLAGS -I/usr/local/include/mbglib/"
LIBS="$LIBS -lmbgdevio"
AC_SEARCH_LIBS([mbg_open_device], [mbgdevio], [ac_have_libmbdevio=yes], [ac_have_libmbdevio=no])
AC_CHECK_HEADERS([mbgdevio.h], [ac_have_mbgdevio_h=yes], [ac_have_mbgdevio_h=no])
#if test "$ac_have_libpthread$ac_have_pthread_h" = yesyes; then
if test "$ac_have_mbgdevio_h" = yes; then
    AC_DEFINE([HAVE_MBGLIB])
else
    CPPFLAGS="$save_cpp"
    LIBS="$save_libs"
fi

AC_ARG_ENABLE([bpf],
    [AS_HELP_STRING([  --disable-bpf], [Compile without BPF support])],
    [:], [enable_bpf=yes])


AC_SEARCH_LIBS([bpf_prog_load_xattr], [bpf], [ac_have_libbpf=yes], [ac_have_libbpf=no])
AC_CHECK_HEADERS([bpf/bpf.h], [ac_have_libbpf_h=yes], [ac_have_libbpf_h=no])
if test "x$ac_have_libbpf$ac_have_libbpf_h$enable_bpf" = "xyesyesyes"; then
    AC_DEFINE([HAVE_BPF])
    have_libbpf=yes
    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <bpf/bpf.h>
    enum bpf_stats_type test;
]], [[]])], ac_cv_bpf_has_bpf_stats_type=yes, ac_cv_bpf_has_bpf_stats_type=no)
    if test "x$ac_cv_bpf_has_bpf_stats_type" = "xyes"; then
        AC_DEFINE([HAVE_BPF_STATS_TYPE])
    fi
else
    have_libbpf=no
    enable_bpf=no
fi

AC_SEARCH_LIBS([curl_global_init], [curl], [ac_have_curl=yes], [ac_have_curl=no])
AC_CHECK_HEADERS([curl/curl.h], [ac_have_curl_h=yes], [ac_have_curl_h=no])
if test "$ac_have_curl$ac_have_curl_h" = yesyes; then
    AC_DEFINE([HAVE_CURL])
fi

AC_SEARCH_LIBS([elf_version], [elf], [ac_have_elf=yes], [ac_have_elf=no])

AC_SEARCH_LIBS([MHD_start_daemon], [microhttpd], [ac_have_libmicrohttpd=yes], [ac_have_libmicrohttpd=no])
AC_CHECK_HEADERS([microhttpd.h], [ac_have_microhttpd_h=yes], [ac_have_microhttpd_h=no])
if test "x$ac_have_libmicrohttpd$ac_have_microhttpd_h" = "xyesyes"; then
    have_httpd=yes
    AC_DEFINE([HAVE_MICROHTTPD])
else
    have_httpd=no
fi

AC_CHECK_LIB([re2], [main], [ac_have_re2=yes], [ac_have_re2=no])
AC_CHECK_HEADERS([re2/re2.h], [ac_have_re2_h=yes], [ac_have_re2_h=no])
if test "x$ac_have_re2$ac_have_re2_h" = "xyesyes"; then
    have_re2=yes
    LIBS="$LIBS -lre2"
    AC_DEFINE([HAVE_RE2])
else
    have_re2=no
fi

AC_CHECK_LIB([hs], [hs_compile_multi], [ac_have_hyperscan=yes], [ac_have_hyperscan=no])
AC_CHECK_HEADERS([hs/hs.h], [ac_have_hyperscan_h=yes], [ac_have_hyperscan_h=no])
if test "x$ac_have_hyperscan$ac_have_hyperscan_h" = "xyesyes"; then
    have_hyperscan=yes
    LIBS="$LIBS -lhs"
    AC_DEFINE([HAVE_HYPERSCAN],[1],[Have the hyperscan library for regex matching.])
else
    have_hyperscan=no
fi

AC_SEARCH_LIBS([PAPI_start_counters], [papi], [ac_have_papi=yes], [ac_have_papi=no])
AC_CHECK_HEADERS([papi.h], [ac_have_papi_h=yes], [ac_have_papi_h=no])
if test "x$ac_have_papi_h$ac_have_papi" = "xyesyes"; then
    AC_DEFINE([HAVE_PAPI],[1],[Have the libpapi library for performance counters.])
    have_papi=yes
else
    have_papi=no
fi

AC_DEFINE([HAVE_JSON])

AC_CHECK_LIB([pci], [main], [ac_have_pci=yes], [ac_have_pci=no])
AC_CHECK_HEADERS([pci/pci.h], [ac_have_pci_h=yes], [ac_have_pci_h=no])
if test "x$ac_have_pci$ac_have_pci_h" = "xyesyes"; then
    have_pci=yes
    LIBS="$LIBS -lpci"
    AC_DEFINE([HAVE_PCI])
else
    have_pci=no
fi

AC_ARG_ENABLE([rand-align],
    [AS_HELP_STRING([  --enable-rand-align], [enable random alignment of element])],
    [:], [enable_rand_align=no])
if test "x$enable_rand_align" = "xyes"; then
    AC_DEFINE([HAVE_RAND_ALIGN])
    AC_SUBST(DO_RAND_ALIGN,1)
else
    AC_SUBST(DO_RAND_ALIGN,0)
fi

AC_ARG_ENABLE([select],
    [AS_HELP_STRING([  --enable-select=[[select|poll|kqueue]]], [set file descriptor wait mechanism])
AS_HELP_STRING([  --disable-select], [do not use select()])],
    [:], [enable_select="select poll kqueue"])
AC_ARG_ENABLE([poll],
    [AS_HELP_STRING([  --disable-poll], [do not use poll()])],
    [:], [enable_poll=yes])
AC_ARG_ENABLE([kqueue],
    [AS_HELP_STRING([  --disable-kqueue], [do not use kqueue()])],
    [:], [enable_kqueue=yes])

if test "$enable_select" = yes; then
    enable_select='select poll kqueue'
elif test "$enable_select" = no; then
    enable_select='poll kqueue'
fi
if echo "$enable_select" | grep select >/dev/null 2>&1; then
    AC_DEFINE([HAVE_ALLOW_SELECT], [1], [Define if select() may be used to wait for file descriptor events.])
fi
if echo "$enable_select" | grep poll >/dev/null 2>&1 && test "$enable_poll" = yes; then
    AC_DEFINE([HAVE_ALLOW_POLL], [1], [Define if poll() may be used to wait for file descriptor events.])
fi
if echo "$enable_select" | grep kqueue >/dev/null 2>&1 && test "$enable_kqueue" = yes; then
    AC_DEFINE([HAVE_ALLOW_KQUEUE], [1], [Define if kqueue() may be used to wait for file descriptor events.])
fi


dnl
dnl check whether tools should be built for host or build
dnl

AC_ARG_ENABLE([dpdk],
    [AS_HELP_STRING([  --enable-dpdk], [use DPDK])],
    [:], [enable_dpdk=no])

AC_ARG_ENABLE([dpdk-pool],
    [AS_HELP_STRING([    --enable-dpdk-pool], [use DPDK buffer instead of standard Click buffer])],
    [:], [enable_dpdk_pool=no])

AC_ARG_ENABLE([dpdk-xchg],
    [AS_HELP_STRING([    --enable-dpdk-xchg], [use DPDK XCHG API])],
    [:], [enable_dpdk_xchg=no])

AC_ARG_ENABLE([dpdk-packet],
    [AS_HELP_STRING([    --enable-dpdk-packet],
                    [Click packets are DPDK packet])],
    [:], [enable_dpdk_packet=no])

AC_ARG_ENABLE([dpdk-softqueue],
    [AS_HELP_STRING([    --disable-dpdk-softqueue],
                    [Do not use internal software queue in TX to buffer packets before flushing.])],
    [:], [AC_DEFINE(HAVE_IQUEUE)])

AC_ARG_ENABLE([flow-api], [AS_HELP_STRING([    --enable-flow-api], [Support for the HW flow classification API. Also needs DPDK>=20.02])], [:], [enable_flow_api=no])


AC_ARG_ENABLE([click-pool],
    [AS_HELP_STRING([    --disable-click-pool], [allow usage of Click Packet pool. It will still only be effectively enabled in specific (but most) cases, see packet.hh])],
    [:], [enable_click_pool=yes;AC_DEFINE(HAVE_ALLOW_CLICK_PACKET_POOL,[1],[Define if Click packet pool can be used if others flags allow it (see packet.hh).])])


AC_ARG_ENABLE([pool-inlining],
    [AS_HELP_STRING([  --disable-pool-inlining],
                    [Do not optimize pool_prepare_data_burst function before  data structure reordering done at the IR level.])],
    [:], [AC_DEFINE(POOL_INLINING)])

AC_ARG_ENABLE([inlined-allanno],
    [AS_HELP_STRING([  --enable-inlined-allanno],
                    [Inline AllAnno struct into Packet class, facilitating the data structure reordering.])],
    [:], [enable_inlined_allanno=no])
if test "x$enable_inlined_allanno" = "xyes"; then
    AC_DEFINE([INLINED_ALLANNO])
fi


AC_ARG_ENABLE([zerocopy],
    [AS_HELP_STRING([  --disable-zerocopy], [disable Zero Copy])],
    [:], [enable_zerocopy=yes])
if test "x$enable_zerocopy" = xyes; then
    AC_DEFINE(HAVE_ZEROCOPY)
fi

AC_ARG_ENABLE([clone],
    [AS_HELP_STRING([  --disable-clone], [disable packet cloning])],
    [AC_DEFINE(CLICK_NOINDIRECT)],[:])

AC_ARG_ENABLE([rsspp],
    [AS_HELP_STRING([  --disable-rsspp], [disable RSS++ (enabled if --enable-cpu-load by default)])],
    [:],[enable_rsspp=yes])

dnl linuxmodule driver and features

AC_ARG_ENABLE([linuxmodule],
    [AS_HELP_STRING([--enable-linuxmodule], [disable Linux kernel driver])],
    [:], [enable_linuxmodule=no; enable_linuxmodule_default=no])

AC_ARG_ENABLE([fixincludes],
    [AS_HELP_STRING([  --disable-fixincludes], [do not patch Linux kernel headers for C++])],
    [:], [enable_fixincludes=yes])
LINUXMODULE_FIXINCLUDES=
if test "$enable_fixincludes" = yes; then
    LINUXMODULE_FIXINCLUDES=1
fi
AC_SUBST(LINUXMODULE_FIXINCLUDES)

AC_ARG_ENABLE([multithread],
    [AS_HELP_STRING([  --enable-multithread], [support kernel multithreading])],
    [:], [enable_multithread=no])

if test "$enable_multithread" != no -a "$enable_multithread" != 1; then
    AC_DEFINE_UNQUOTED(__MTCLICK__, 1)
    AC_DEFINE_UNQUOTED(HAVE_LINUXMODULE_MULTITHREAD, 1)
    saveflags="$CPPFLAGS"
    CPPFLAGS="$saveflags -D__MTCLICK__"
else
    enable_multithread=no
fi

AC_ARG_ENABLE([warp9],
    [AS_HELP_STRING([  --enable-warp9], [reduce PollDevice functionality for speed])],
    [:], [enable_warp9=no])
if test "x$enable_warp9" = xyes; then
    AC_DEFINE(CLICK_WARP9)
fi

AC_DEFINE(HAVE_CLICKFS)

AC_ARG_ENABLE([kassert],
    [AS_HELP_STRING([  --enable-kassert], [enable kernel assertions])],
    [:], [enable_kassert=no])
if test $enable_kassert = yes; then
    AC_DEFINE(HAVE_KERNEL_ASSERT)
fi

AC_ARG_ENABLE([adaptive],
    [AS_HELP_STRING([  --enable-adaptive], [use adaptive scheduler to flexibly arbitrate
                              between Click and the kernel (EXPERIMENTAL)])],
    [:], [enable_adaptive=no])
if test "x$enable_adaptive" = xyes; then
    AC_DEFINE(HAVE_ADAPTIVE_SCHEDULER)
fi

AC_ARG_ENABLE([linux-symbols],
    [AS_HELP_STRING([  --disable-linux-symbols], [do not export Click symbols (breaks packages)])],
    [:], [enable_linux_symbols=yes])
INCLUDE_KSYMS=no
if test "x$enable_linux_symbols" = xyes; then
    INCLUDE_KSYMS=yes
fi
AC_SUBST(INCLUDE_KSYMS)


dnl bsdmodule driver and features

AC_ARG_ENABLE([bsdmodule],
    [AS_HELP_STRING([--enable-bsdmodule], [enable FreeBSD kernel driver (EXPERIMENTAL)])],
    [:], [enable_bsdmodule=no])

AC_ARG_ENABLE([netisr],
    [AS_HELP_STRING([  --disable-netisr], [disable NETISR scheduling in BSD])],
    [:], [enable_netisr=yes])
if test $enable_netisr = yes; then
    AC_DEFINE(BSD_NETISRSCHED)
fi


dnl nsclick driver and features

AC_ARG_ENABLE([nsclick],
    [AS_HELP_STRING([--enable-nsclick], [enable NS simulator driver])],
    [:], [enable_nsclick=no])


dnl minios driver

AC_ARG_ENABLE([minios],
     [AS_HELP_STRING([--enable-minios], [enable MiniOS application])],
     [:], [enable_minios=no])

AC_ARG_WITH([xen],
    [AS_HELP_STRING([[--with-xen[=PATH]]], [Xen source code is in PATH])],
    [xenpath=$withval], [xenpath=NONE])
AC_ARG_WITH([minios],
    [AS_HELP_STRING([[--with-minios[=PATH]]], [MiniOS source code is in PATH])],
    [miniospath=$withval], [miniospath=NONE])
AC_ARG_WITH([newlib],
    [AS_HELP_STRING([[--with-newlib[=PATH]]], [Newlib is installed in PATH])],
    [newlibpath=$withval], [newlibpath=NONE])
AC_ARG_WITH([lwip],
    [AS_HELP_STRING([[--with-lwip[=PATH]]], [Lwip is installed in PATH])],
    [lwippath=$withval], [lwippath=NONE])

if test "$enable_minios" = yes; then
    if test "$xenpath" = NONE; then
        xenpath="../xen"
    fi
    if test "$miniospath" = NONE; then
        miniospath="../mini-os"
    fi
    if test "$newlibpath" = NONE; then
        newlibpath="../toolchain/x86_64-root/x86_64-xen-elf"
    fi
    if test "$lwippath" = NONE; then
        lwippath="../toolchain/x86_64-root/x86_64-xen-elf"
    fi

    xenpath="`readlink -f $xenpath`"
    if test ! -d "$xenpath"; then
        AC_MSG_ERROR([
=========================================

Can't find $xenpath, so I can't compile the minios driver!
(You may need the --with-xen=DIR option.)

=========================================])
    fi
    miniospath="`readlink -f $miniospath`"
    if test ! -d "$miniospath"; then
        AC_MSG_ERROR([
=========================================

Can't find $miniospath, so I can't compile the minios driver!
(You may need the --with-minios=DIR option.)

=========================================])
    fi
    newlibpath="`readlink -f $newlibpath`"
    if test ! -d "$newlibpath"; then
        AC_MSG_ERROR([
=========================================

Can't find $newlibpath, so I can't compile the minios driver!
(You may need the --with-newlib=DIR option.)

=========================================])
    fi
    lwippath="`readlink -f $lwippath`"
    if test ! -d "$lwippath"; then
        AC_MSG_ERROR([
=========================================

Can't find $lwippath, so I can't compile the minios driver!
(You may need the --with-lwip=DIR option.)

=========================================])
    fi

    xen_dir=$xenpath
    AC_SUBST(xen_dir)
    minios_dir=$miniospath
    AC_SUBST(minios_dir)
    newlib_dir=$newlibpath
    AC_SUBST(newlib_dir)
    lwip_dir=$lwippath
    AC_SUBST(lwip_dir)
fi


dnl
dnl How to build linuxmodule driver?
dnl

AC_ARG_WITH([linux],
    [AS_HELP_STRING([[--with-linux[=PATH]]], [Linux source code is in PATH])],
    [linuxpath=$withval], [linuxpath=NONE])
test -z "$linuxpath" -o "$linuxpath" = yes && linuxpath=yes

AC_ARG_WITH([linux-map],
    [AS_HELP_STRING([[--with-linux-map[=FILE]]], [filename for Linux System.map [LINUXDIR/System.map]])],
    [linux_system_map=$withval; if test -z "$withval" -o "$withval" = yes; then linux_system_map=NONE; fi],
    [linux_system_map=NONE])

linux_system_map_boot=no

if test "x$linuxpath" = xNONE -o "x$linuxpath" = xyes; then
    if uname -r 2>/dev/null | grep '^\(2\.6\|3\.\)' >/dev/null 2>&1; then
        linuxpath=/lib/modules/"`uname -r`"/build
        linux_system_map_boot="`uname -r`"
    else
        linuxpath=/usr/src/linux
    fi
    if test ! -d "$linuxpath" -a "x$enable_linuxmodule" = xyes; then
        if test "x$enable_linuxmodule_default" = xyes; then
            linuxpath=NONE; enable_linuxmodule=no
        else
            AC_MSG_ERROR([
=========================================

Can't find $linuxpath, so I can't compile the linuxmodule driver!
(You may need the --with-linux=DIR option.)

=========================================])
        fi
    fi
fi

dnl find files in the Linux path
find_linuxpath () {
    path="$linuxpath"
    while test -n "$path"; do
        l=`echo "$path" | sed 's/^\([[^:]]*\).*/\1/'`
        path=`echo "$path" | sed 's/^[[^:]]*:*//'`
        if test -n "$l" -a -f "$l/$1"; then
            echo "$l/$1"
            return
        fi
    done
    echo "/nonexistent_file"
}

if test "x$linuxpath" = xNONE -o "x$linuxpath" = xno -o "x$enable_linuxmodule" != xyes; then
    ac_have_linux_kernel=n
    linuxpath=NONE
    linux_srcdir=NONE
    linux_builddir=NONE
else
    dnl check $linuxpath for relative directories
    path="$linuxpath"
    while test -n "$path"; do
        l=`echo "$path" | sed 's/^\([[^:]]*\).*/\1/'`
        path=`echo "$path" | sed 's/^[[^>]]*:*//'`
        if test -n "$l" && expr "_$l" : '_[[^/\\]]' >/dev/null; then
            AC_MSG_ERROR([
=========================================

The --with-linux directory $l is relative.
All Linux directories must be absolute paths starting with /.

=========================================])
        fi
    done

    linux_skbuff_h=`find_linuxpath include/linux/skbuff.h`
    if test -r "$linux_skbuff_h"; then
        linux_srcdir=`echo "$linux_skbuff_h" | sed 's_include/linux/skbuff\.h__'`
        ac_have_linux_kernel=y
    else
        AC_MSG_ERROR([
=========================================

Can't find include/linux/skbuff.h in $linuxpath.
Are you sure $linuxpath contains Linux kernel source?

=========================================])
        dnl ' fix syntax highlighting
    fi

    linux_config=`find_linuxpath .config`
    if test -r "$linux_config"; then
        linux_builddir=`echo "$linux_config" | sed 's_/\.config__'`
    else
        AC_MSG_ERROR([
=========================================

Can't find .config in $linuxpath.
Are you sure $linuxpath contains a Linux kernel build?

=========================================])
        dnl ' fix syntax highlighting
    fi
fi

AC_SUBST(linux_builddir)
AC_SUBST(linux_srcdir)
AC_DEFINE_UNQUOTED(LINUX_SRCDIR, "${linux_srcdir}")



dnl
dnl element collections
dnl

AC_ARG_ENABLE([all-elements], [AS_HELP_STRING([--enable-all-elements], [include all provided element groups])])

dnl ELEMENTS_ARG_ENABLE(COLLECTION, HELP-STRING, DEFAULT-VALUE, IF_YES, COND_FOR_ENABLE_ALL)
element_groups=""
AC_SUBST(element_groups)
AC_DEFUN([ELEMENTS_ARG_ENABLE],
[AC_ARG_ENABLE($1, [  --]builtin(substr, builtin(ifelse, [$3], yes, dis, en)[able-$1              ], 0, 21)[ ]builtin(ifelse, [$3], yes, [do not ], [])[$2], ,
[enable_]patsubst([$1], -, _)=$3)dnl
test "x$enable_all_elements" = xyes -a \( ["x$enable_]patsubst([$1], -, _)["] = xNO -o ["x$enable_]patsubst([$1], -, _)["] = x \)$5 && [enable_]patsubst([$1], -, _)[=yes]
if test ["x$enable_]patsubst([$1], -, _)["] = xyes; then
    :
    $4
fi])

ELEMENTS_ARG_ENABLE(analysis, [include elements for network analysis], yes)
ELEMENTS_ARG_ENABLE(app, [include application-level elements], yes)
ELEMENTS_ARG_ENABLE(aqm, [include active queue management elements], yes)
ELEMENTS_ARG_ENABLE(ethernet, [include Ethernet elements], yes)
ELEMENTS_ARG_ENABLE(etherswitch, [include Ethernet switch elements], NO)
ELEMENTS_ARG_ENABLE(flow, [include Enable flow system and elements], NO, enable_flow=yes, [ -a "x$enable_batch" = xyes ] )
ELEMENTS_ARG_ENABLE(ctx, [include Context-based elements], NO, enable_ctx=yes , [ -a "x$enable_flow" = xyes ] )
ELEMENTS_ARG_ENABLE(grid, [include Grid elements (see FAQ)], NO)
ELEMENTS_ARG_ENABLE(icmp, [include ICMP elements], yes)
ELEMENTS_ARG_ENABLE(ip, [include IP elements], yes)
ELEMENTS_ARG_ENABLE(ip6, [include IPv6 elements], NO, AC_DEFINE(HAVE_IP6))
ELEMENTS_ARG_ENABLE(ipsec, [include IP security elements], NO, AC_DEFINE(HAVE_IPSEC))
ELEMENTS_ARG_ENABLE(local, [include local elements], NO)
ELEMENTS_ARG_ENABLE(radio, [include radio elements], NO)
ELEMENTS_ARG_ENABLE(research, [include research elements], NO)
ELEMENTS_ARG_ENABLE(simple, [include simple versions of other elements], yes)
dnl ELEMENTS_ARG_ENABLE(snmp, [include SNMP elements], NO)
ELEMENTS_ARG_ENABLE(standard, [include standard elements], yes)
ELEMENTS_ARG_ENABLE(tcpudp, [include TCP and UDP elements], yes)
ELEMENTS_ARG_ENABLE(test, [include regression test elements], yes)
ELEMENTS_ARG_ENABLE(threads, [include thread management elements], yes)
ELEMENTS_ARG_ENABLE(tunnel, [include tunnelling elements], NO)
ELEMENTS_ARG_ENABLE(wifi, [include wifi elements and support], NO)
AC_ARG_ENABLE(experimental, [AS_HELP_STRING([--enable-experimental], [enable experimental elements in normal groups])], :, enable_experimental=no)
AC_ARG_ENABLE(skip-elements, [AS_HELP_STRING([--enable-skip-elements=ELTS], [disable comma-separated elements])], :, enable_skip_elements=no)

all_element_groups=
for i in `(cd $srcdir/elements; ls | sed '/^CVS$/d;/^\.git/d;/^bsdmodule$/d;/^linuxmodule$/d;/^ns$/d;/^userlevel$/d;/^minios$/d')`; do
    enableval=`eval 'echo $'"enable_$i"`
    test "x$enable_all_elements" = xyes -a "x$enableval" '=' xyes && enableval=yes
    test -d "$srcdir/elements/$i" -a "$enableval" = "yes" && element_groups="$element_groups $i"
    test -d "$srcdir/elements/$i" && all_element_groups="$all_element_groups$i "
done
AC_SUBST([all_element_groups])

FINDELEMFLAGS=
if test "x$enable_skip_elements" != xno -a "x$enable_skip_elements" != xyes; then
    FINDELEMFLAGS="-x '$enable_skip_elements'"
fi
AC_SUBST([FINDELEMFLAGS])


dnl
dnl How to build bsdmodule driver?
dnl

AC_ARG_WITH(freebsd, [[  --with-freebsd[=SRC,INC] FreeBSD source code is in SRC [/usr/src/sys],
                          include directory is INC [/usr/include]]],
  [freebsddir=$withval; if test -z "$withval" -o "$withval" = yes; then freebsddir=/usr/src/sys,/usr/include; fi],
  freebsddir=NONE)

if test "x$freebsddir" = xNONE; then
  if test -d /usr/src/sys -a -d /usr/include; then
    freebsddir=/usr/src/sys,/usr/include
  elif test "x$enable_bsdmodule" = xyes; then
    AC_MSG_WARN([
=========================================

Can't find /usr/src/sys and/or /usr/include, so I'm not compiling
the bsdmodule driver.  (You may need the --with-freebsd=DIR option.)

=========================================])
  fi
fi

freebsd_srcdir=`echo "$freebsddir," | sed -e 's/,.*//'`
freebsd_includedir=`echo "$freebsddir,/usr/include," | sed -e 's/^[[^,]]*,\([[^,]]*\),.*$/\1/'`

if test "x$freebsddir" = xNONE -o "x$freebsddir" = xno -o "x$enable_bsdmodule" != xyes; then
  ac_have_bsd_kernel=n
  freebsddir=NONE
elif expr '(' "_$freebsd_includedir" : '_[[^/\\]]' ')' '|' '(' "_$freebsd_srcdir" : '_[[^/\\]]' ')'; then
  AC_MSG_ERROR([
=========================================

The --with-freebsd directories $freebsd_srcdir,$freebsd_includedir
are relative.  You must supply absolute paths starting with /.

=========================================])
elif test -r $freebsd_includedir/net/if_var.h -a -r $freebsd_srcdir/kern/vnode_if.src; then
  ac_have_bsd_kernel=y
else
  AC_MSG_ERROR([
=========================================

Can't find $freebsd_includedir/net/if_var.h and/or
$freebsd_srcdir/kern/vnode_if.src.  Are you sure $freebsd_srcdir
and $freebsd_includedir contain FreeBSD kernel source?

=========================================])
  dnl ' fix syntax highlighting
fi

AC_SUBST(freebsd_srcdir)
AC_SUBST(freebsd_includedir)
AC_DEFINE_UNQUOTED(FREEBSD_INCLUDEDIR, "${freebsd_includedir}")


dnl
dnl check whether target is Linux
dnl

AC_CACHE_CHECK([whether we are compiling for Linux], [ac_cv_under_linux],
    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __linux__
#error "unsupported"
#endif
return 0;]])], ac_cv_under_linux=yes, ac_cv_under_linux=no)])

AC_CACHE_CHECK([whether we are compiling for Apple Mach], [ac_cv_under_mach],
    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#if !(defined(__MACH__) && defined(__APPLE__))
#error "unsupported"
#endif
return 0;]])], ac_cv_under_mach=yes, ac_cv_under_mach=no)])


dnl
dnl functions
dnl

AC_LANG([C])
AC_REPLACE_FUNCS(strerror)
AC_CHECK_FUNCS(random snprintf strnlen strtof strtold strtoul tcgetpgrp vsnprintf aligned_alloc)
AC_LANG([C++])


dnl
dnl integer types, endianness, int64, addressable va_list
dnl

AC_ARG_ENABLE([smaller-code],
    [AS_HELP_STRING([--enable-smaller-code], [generate smaller code (sometimes slower)])],
    [:], [enable_smaller_code=no])
if test "x$enable_smaller_code" = xyes; then
    AC_DEFINE([CLICK_OPTIMIZE_SIZE], [1], [Define to generate smaller object files.])
fi

AC_ARG_ENABLE([int64],
    [AS_HELP_STRING([--disable-int64], [disable 64-bit integer support])],
    [:], [enable_int64=yes])

AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(size_t)
AC_CHECK_SIZEOF(ptrdiff_t)
AC_CHECK_SIZEOF([void *])
CLICK_CHECK_INTEGER_TYPES
CLICK_CHECK_ALIGNMENT
if test "x$enable_int64" = xyes; then
    AC_CHECK_SIZEOF([long long])
    CLICK_CHECK_INT64_TYPES
fi
CLICK_CHECK_ENDIAN
CLICK_CHECK_SIGNED_SHIFT
CLICK_CHECK_ADDRESSABLE_VA_LIST
CLICK_CHECK_COMPILER_INTRINSICS

AX_CXX_COMPILE_STDCXX(17,[],optional)


dnl
dnl timestamps
dnl

AC_CHECK_HEADERS_ONCE([time.h])
AC_CHECK_SIZEOF([struct timeval])
AC_CHECK_TYPES([struct timespec], [have_timespec=yes], [have_timespec=no],
               [AC_INCLUDES_DEFAULT
[#ifdef HAVE_TIME_H]
[# include <time.h>]
[#endif]])
if test "x$have_timespec" = xyes; then
    AC_CHECK_SIZEOF([struct timespec])
fi
CLICK_CHECK_POSIX_CLOCKS

AC_ARG_ENABLE([nanotimestamp],
    [AS_HELP_STRING([--enable-nanotimestamp], [enable nanosecond timestamps (default if clock_gettime is available)])])
# Default to nanosecond-precision timestamps if clock_gettime is available.
if test "x$enable_nanotimestamp" = x -a "x$have_clock_gettime" = xyes; then
    enable_nanotimestamp=yes
fi
if test "x$enable_nanotimestamp" = xyes; then
    AC_DEFINE([HAVE_NANOTIMESTAMP_ENABLED], [1], [Define if nanosecond-granularity timestamps are enabled.])
fi

AC_ARG_ENABLE([simtime],
    [AS_HELP_STRING([--enable-simtime], [enable support for simulated timing])],
    [AC_DEFINE([HAVE_SIMTIME])], [enable_simtime=no])

AC_ARG_ENABLE([user_timestamp],
    [AS_HELP_STRING([--enable-user-timestamp], [enable support for user-provided clock system])],
    [:], [enable_user_timestamp=no])

if test "x$enable_user_timestamp" = xyes; then
if test "x$have_int64_types" != xyes; then
    AC_MSG_ERROR([
=========================================

User-based timestamp needs 64bits types !

=========================================])
fi
    AC_DEFINE([HAVE_USER_TIMING], [1], [Define if user-provided clock system is supported.])
fi

dnl
dnl check forms of port transfer
dnl

AC_ARG_ENABLE(bound-port-transfer,
  [AS_HELP_STRING([--enable-bound-port-transfer], [enable port transfer function ptr optimization])],
  :, enable_bound_port_transfer=no)

if test "$enable_bound_port_transfer" = yes; then
  AC_DEFINE([HAVE_BOUND_PORT_TRANSFER], [1], [Define if Port::push/Port::pull should use bound function pointers.])
  if test -z "${CXX##*clang*}" ; then
      AC_MSG_ERROR([--enable-bound-port-transfer does not work with Clang! A better solution is to use click-devirtualize in any case. Remove this option or use GCC (you probably have your CXX environment variable set to clang++).])
  fi
  CXXFLAGS="$CXXFLAGS -Wno-pmf-conversions"
fi

AX_CHECK_COMPILE_FLAG([-faligned-new], [have_aligned_new=yes], [have_aligned_new=no])
if test "x$have_aligned_new" = xyes; then
    CXXFLAGS="$CXXFLAGS -faligned-new"
fi


if test "x$enable_flow" = xyes; then
    if test "x$enable_batch" != xyes; then
        AC_MSG_ERROR([--enable-flow needs --enable-batch! Flow subsystem will be disabled.])
    else
        AC_DEFINE(HAVE_FLOW)
    fi
    AC_SUBST(USE_FLOW, yes)
fi

if test "x$enable_ctx" = xyes; then
    AC_DEFINE(HAVE_CTX)
    AC_SUBST(USE_CTX, yes)
else
    enable_ctx="no"
fi

m4_divert_once([HELP_ENABLE], [[  Optional features about flow and context:]])

AC_ARG_ENABLE([ctx-global-timeout],
    [AS_HELP_STRING([  --disable-ctx-global-timeout], [disable sloppy CTX timeouts. Enabled if CTX is enabled by default.])],
    [:], [enable_ctx_global_timeout=$enable_ctx])
if test "x$enable_ctx_global_timeout" = xyes; then
    AC_DEFINE(HAVE_CTX_GLOBAL_TIMEOUT)
fi

AC_ARG_ENABLE([flow-atomic],
    [AS_HELP_STRING([  --disable-flow-atomic], [use non-atomic flow reference counting])],
    [:], [enable_flow_atomic=yes])
if test "x$enable_flow_atomic" = xyes; then
    AC_DEFINE(FLOW_ATOMIC_USE_COUNT)
fi

AC_ARG_ENABLE([flow-dynamic],
    [AS_HELP_STRING([  --enable-flow-dynamic], [enable dynamic reference counting to automatically acquire and relealse flow control blocksic flow system])],
    [:], [enable_flow_dynamic=no])
if test "x$enable_flow$enable_flow_dynamic" = xyesyes; then
    AC_DEFINE(HAVE_FLOW_DYNAMIC)
fi

AC_ARG_ENABLE([flow-structure],
              [AS_HELP_STRING([  --disable-flow-structure], [do not free classifier nodes in pool, mark them as released to somehow keep the receive strucutre intact])],
    [:], [enable_flow_structure=yes])
if test "x$enable_flow_structure" = xyes; then
    AC_DEFINE(FLOW_KEEP_STRUCTURE)
fi

AC_ARG_ENABLE([flow-hash],
    [AS_HELP_STRING([  --enable-flow-hash=[[reset|keep|epoch]]], [set flow hashtable release mechanism])],
    [:], [enable_flow_hash=""])

if echo "$enable_flow_hash" | grep epoch >/dev/null 2>&1; then
    AC_DEFINE([FLOW_HASH_RELEASE], [2], [Flow hash is in epoch mode.])
elif echo "$enable_flow_hash" | grep keep >/dev/null 2>&1; then
    AC_DEFINE([FLOW_HASH_RELEASE], [1], [Flow hash is in keep mode.])
elif echo "$enable_flow_hash" | grep reset >/dev/null 2>&1; then
    AC_DEFINE([FLOW_HASH_RELEASE], [0], [Flow hash is in reset mode.])
else
    if test "x$enable_flow_structure" = xyes; then
        AC_DEFINE([FLOW_HASH_RELEASE], [1], [Flow hash is in keep mode.])
    else
        AC_DEFINE([FLOW_HASH_RELEASE], [2], [Flow hash is in epoch mode.])
    fi
fi

AC_ARG_ENABLE(tools,
  [AS_HELP_STRING([--enable-tools=WHERE],[enable tools (host/build/mixed/no) [[mixed]]])],
  :, enable_tools=mixed)

if test "$enable_tools" != mixed -a "$enable_tools" != host -a "$enable_tools" != build -a "$enable_tools" != no; then
  AC_MSG_ERROR([
=========================================

Bad value for --enable-tools.  Try 'host', 'build', 'mixed', or 'no'.

=========================================])
elif test "$enable_tools" = no; then
  HOST_TOOLS=host
elif test "$cross_compiling" = no -o "$enable_tools" = host; then
  HOST_TOOLS=host
else
  dnl This is wrong!! Should at least check that HOST_CC and HOST_CXX work.
  AC_CHECK_PROGS(BUILD_CC, gcc)
  AC_CHECK_PROGS(BUILD_CXX, g++)
  CLICK_PROG_BUILD_CXX
  AC_CHECK_PROGS(BUILD_AR, ar)
  AC_CHECK_PROGS(BUILD_RANLIB, ranlib, :)
  HOST_TOOLS=$enable_tools
fi
AC_SUBST(HOST_TOOLS)


dnl
dnl headers, event detection, dynamic linking
dnl

AC_ARG_ENABLE(dynamic-linking,
  [AS_HELP_STRING([--disable-dynamic-linking], [disable dynamic linking])],
  :, enable_dynamic_linking=yes)
if test "x$enable_dynamic_linking" = xyes; then
    CLICK_CHECK_DYNAMIC_LINKING
    if test "$HOST_TOOLS" != host -a "$enable_tools" != no; then
        CLICK_CHECK_BUILD_DYNAMIC_LINKING
    fi
    CLICK_SHARED=1
else
    CLICK_SHARED=0
fi
AC_SUBST(CLICK_SHARED)

AC_CHECK_HEADERS_ONCE([termio.h netdb.h sys/event.h pwd.h grp.h execinfo.h])
CLICK_CHECK_POLL_H
AC_CHECK_FUNCS([pselect sigaction])

AC_CHECK_FUNCS([kqueue], [have_kqueue=yes])
if test "x$have_kqueue" = xyes; then
    AC_CACHE_CHECK([whether EV_SET last argument is void *], [ac_cv_ev_set_udata_pointer],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>]], [[struct kevent kev; EV_SET(&kev, 1, EVFILT_WRITE, EV_ADD, 0, 0, (void *) &kev);]])], [ac_cv_ev_set_udata_pointer=yes], [ac_cv_ev_set_udata_pointer=no])])
    if test $ac_cv_ev_set_udata_pointer = yes; then
        AC_DEFINE([HAVE_EV_SET_UDATA_POINTER], [1], [Define if the last argument to EV_SET has pointer type.])
    fi
fi

dnl
dnl sockets
dnl

AC_LANG([C])
SOCKET_LIBS=
if test "$enable_userlevel" = yes; then
    savelibs="$LIBS"; LIBS=
    AC_SEARCH_LIBS(gethostbyname, nsl, , , $savelibs)
    AC_SEARCH_LIBS(connect, socket, , , $savelibs)
    SOCKET_LIBS="$LIBS"; LIBS="$savelibs"

    AC_CACHE_CHECK([whether accept() uses socklen_t], [ac_cv_accept_socklen_t],
            [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <sys/socket.h>
]], [[socklen_t sl; (void) accept(0, (struct sockaddr *) 0, &sl);]])],
        ac_cv_accept_socklen_t=yes, ac_cv_accept_socklen_t=no)])
    if test "$ac_cv_accept_socklen_t" = yes; then
        AC_DEFINE([HAVE_ACCEPT_SOCKLEN_T], [1], [Define if accept() uses socklen_t.])
    fi
fi
AC_SUBST(SOCKET_LIBS)
AC_LANG([C++])


dnl
dnl large file support
dnl

CLICK_CHECK_LARGE_FILE_SUPPORT


dnl
dnl mmap
dnl

AC_LANG([C])
AC_CHECK_HEADERS_ONCE([sys/mman.h])
AC_FUNC_MMAP
AC_LANG([C++])
AC_CHECK_FUNCS(madvise)
AC_CHECK_DECLS(madvise, [], [], [#if HAVE_SYS_MMAN_H
#include <sys/types.h>
#include <sys/mman.h>
#endif])


dnl
dnl objects required by element collections
dnl

if test "x$enable_ip6" = xyes; then
    EXTRA_DRIVER_OBJS="ip6address.o ip6flowid.o ip6table.o $EXTRA_DRIVER_OBJS"
    EXTRA_TOOL_OBJS="ip6address.o $EXTRA_TOOL_OBJS"
fi
AC_SUBST(EXTRA_DRIVER_OBJS)
AC_SUBST(EXTRA_TOOL_OBJS)


dnl
dnl stuff in the linux kernel
dnl

if test $ac_have_linux_kernel = y; then

dnl Look for System.map

if test "$linux_system_map" = NONE; then
    linux_system_map=`find_linuxpath System.map`
    if test "x$linux_system_map_boot" != xno -a ! -f "$linux_system_map"; then
        linux_system_map=/boot/System.map-"$linux_system_map_boot"
    fi
fi

AC_MSG_CHECKING([for Linux System.map])
if test -r "$linux_system_map"; then
    AC_MSG_RESULT([$linux_system_map])
elif test -f "$linux_system_map"; then
    AC_MSG_RESULT([$linux_system_map (unreadable)])
    AC_MSG_ERROR([
=========================================

$linux_system_map exists, but is unreadable.
Run 'sudo ./configure', run 'sudo chmod go+r $linux_system_map',
or use the --with-linux=DIR and/or --with-linux-map=MAP options.

=========================================])
else
    if test "x$enable_linuxmodule_default" = xyes; then
        AC_MSG_WARN([
=========================================

Can't find Linux System.map file $linux_system_map,
so I won't compile the linuxmodule driver.
(You may need the --with-linux=DIR and/or --with-linux-map=MAP options.)

=========================================])
        ac_have_linux_kernel=no
    else
        if test "$linux_system_map" = /nonexistent_file; then
            linux_system_map="in $linuxpath"
        fi
        AC_MSG_ERROR([
=========================================

Can't find Linux System.map file $linux_system_map.
(You may need the --with-linux=DIR and/or --with-linux-map=MAP options.)

=========================================])
        dnl ' fix syntax highlighting
    fi
fi

fi

dnl Check for Linux 2.6

if test $ac_have_linux_kernel = y; then

AC_MSG_CHECKING([Linux version])
linuxpath_makefile=`find_linuxpath Makefile`
linux_version=`grep '^VERSION[[         ]]*=[[  ]]*[[0-9]][[0-9]]*[[    ]]*$' "$linuxpath_makefile" | tr -c -d 0-9`
linux_patchlevel=`grep '^PATCHLEVEL[[   ]]*=[[  ]]*[[0-9]][[0-9]]*[[    ]]*$' "$linuxpath_makefile" | tr -c -d 0-9`
linux_sublevel=`grep '^SUBLEVEL[[       ]]*=[[  ]]*[[0-9]][[0-9]]*[[    ]]*$' "$linuxpath_makefile" | tr -c -d 0-9`
if test -n "$linux_version" -a -n "$linux_patchlevel" -a -z "$linux_sublevel"; then linux_sublevel=0; fi
if test -n "$linux_version" -a -n "$linux_patchlevel" -a -n "$linux_sublevel"; then
    AC_MSG_RESULT([$linux_version.$linux_patchlevel.$linux_sublevel])
    linux_version_code=`expr $linux_version '*' 65536 + $linux_patchlevel '*' 256 + $linux_sublevel`
else
    AC_MSG_RESULT([unknown])
    linux_version_code=0
fi

LINUXMODULE_2_6=0
if test "$linux_version.$linux_patchlevel" = 2.6 -o "$linux_version" -ge 3; then
    LINUXMODULE_2_6=1
    AC_DEFINE([HAVE_LINUXMODULE_2_6], [1], [Define if the Click linuxmodule is compiled for a 2.6 or later kernel.])
fi
if test "$LINUXMODULE_2_6" = 0; then
    AC_MSG_ERROR([
=========================================

Click no longer supports in-kernel compilation on Linux 2.4 kernels.
Update your Linux or try an older version of Click.

=========================================])
fi
AC_SUBST(LINUXMODULE_2_6)

AC_CACHE_CHECK([for Click Linux kernel extensions], ac_cv_click_kernel,
[if grep "register_net_in" $linux_system_map >/dev/null 2>&1; then
    ac_cv_click_kernel=yes
else ac_cv_click_kernel=no; fi])
if test $ac_cv_click_kernel = yes; then
    AC_DEFINE(HAVE_CLICK_KERNEL)
fi

AC_CACHE_CHECK([for Click Linux kernel extensions for transmit notification], ac_cv_click_kernel_tx_notify,
[if grep "register_net_tx" $linux_system_map >/dev/null 2>&1; then
    ac_cv_click_kernel_tx_notify=yes
else ac_cv_click_kernel_tx_notify=no; fi])
if test $ac_cv_click_kernel_tx_notify = yes; then
    AC_DEFINE(HAVE_CLICK_KERNEL_TX_NOTIFY)
fi

AC_CACHE_CHECK([for read_net_skbcount kernel extension], ac_cv_linux_read_net_skbcount,
[if grep "read_net_skbcount" $linux_system_map >/dev/null 2>&1; then
  ac_cv_linux_read_net_skbcount=yes
else ac_cv_linux_read_net_skbcount=no; fi])
if test $ac_cv_linux_read_net_skbcount = yes; then
    AC_DEFINE(HAVE_LINUX_READ_NET_SKBCOUNT)
fi

AC_CACHE_CHECK([for strlen kernel symbol], ac_cv_linux_strlen_exposed,
[if grep ' strlen' $linux_system_map >/dev/null 2>&1; then
  ac_cv_linux_strlen_exposed=yes
else ac_cv_linux_strlen_exposed=no; fi])
if test $ac_cv_linux_strlen_exposed = yes; then
    AC_DEFINE(HAVE_LINUX_STRLEN_EXPOSED)
fi

AC_CACHE_CHECK([for tulip_interrupt_hook kernel symbol], ac_cv_linux_tulip_intr_hook,
[if grep ' tulip_interrupt_hook' $linux_system_map >/dev/null 2>&1; then
  ac_cv_linux_tulip_intr_hook=yes
else ac_cv_linux_tulip_intr_hook=no; fi])
if test $ac_cv_linux_tulip_intr_hook = yes; then
    AC_DEFINE(HAVE_LINUX_TULIP_INTERRUPT_HOOK)
fi

AC_CACHE_CHECK([for files_lock kernel symbol], ac_cv_linux_files_lock,
[if grep "__ksymtab_files_lock" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_files_lock=yes
else ac_cv_linux_files_lock=no; fi])
if test $ac_cv_linux_files_lock = yes; then
    AC_DEFINE(HAVE_LINUX_FILES_LOCK)
fi

AC_CACHE_CHECK([for files_lglock kernel symbol], ac_cv_linux_files_lglock,
[if grep "__ksymtab_files_lglock" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_files_lglock=yes
else ac_cv_linux_files_lglock=no; fi])
if test $ac_cv_linux_files_lglock = yes; then
    AC_DEFINE(HAVE_LINUX_FILES_LGLOCK)
fi

AC_CACHE_CHECK([for sb_lock kernel symbol], ac_cv_linux_sb_lock,
[if grep "__ksymtab_sb_lock" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_sb_lock=yes
else ac_cv_linux_sb_lock=no; fi])
if test $ac_cv_linux_sb_lock = yes; then
    AC_DEFINE(HAVE_LINUX_SB_LOCK)
fi

AC_CHECK_HEADERS(asm/ioctl.h, have_asm_ioctl_h=yes, have_asm_ioctl_h=no)
if test "$have_asm_ioctl_h" = yes; then
    AC_DEFINE([HAVE_ASM_IOCTL_H])
fi


AC_CACHE_CHECK([for dev_ioctl kernel symbol], ac_cv_linux_dev_ioctl,
[if grep "__ksymtab_dev_ioctl" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_dev_ioctl=yes
else ac_cv_linux_dev_ioctl=no; fi])
if test $ac_cv_linux_dev_ioctl = yes; then
    AC_DEFINE(HAVE_LINUX_DEV_IOCTL)
fi

AC_CACHE_CHECK([for devinet_ioctl kernel symbol], ac_cv_linux_devinet_ioctl,
[if grep "__ksymtab_devinet_ioctl" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_devinet_ioctl=yes
else ac_cv_linux_devinet_ioctl=no; fi])
if test $ac_cv_linux_devinet_ioctl = yes; then
    AC_DEFINE(HAVE_LINUX_DEVINET_IOCTL)
fi

AC_CACHE_CHECK([for inet_ioctl kernel symbol], ac_cv_linux_inet_ioctl,
[if grep "__ksymtab_inet_ioctl" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_inet_ioctl=yes
else ac_cv_linux_inet_ioctl=no; fi])
if test $ac_cv_linux_inet_ioctl = yes; then
    AC_DEFINE(HAVE_LINUX_INET_IOCTL)
fi

AC_CACHE_CHECK([for inet_ctl_sock_create kernel symbol], ac_cv_linux_inet_ctl_sock_create,
[if grep "__ksymtab_inet_ctl_sock_create" $linux_system_map >/dev/null 2>&1; then
    ac_cv_linux_inet_ctl_sock_create=yes
else ac_cv_linux_inet_ctl_sock_create=no; fi])
if test $ac_cv_linux_inet_ctl_sock_create = yes; then
    AC_DEFINE(HAVE_LINUX_INET_CTL_SOCK_CREATE)
fi

AC_CACHE_CHECK([for <linux/ktime.h>], ac_cv_linux_ktime_h,
[if grep ktime_t `find_linuxpath include/linux/ktime.h` >/dev/null 2>&1; then
  ac_cv_linux_ktime_h=yes
else ac_cv_linux_ktime_h=no; fi])
if test $ac_cv_linux_ktime_h = yes; then
    AC_DEFINE(HAVE_LINUX_KTIME_H)
fi

fi


dnl
dnl stuff in the bsd kernel
dnl

if test $ac_have_bsd_kernel = y; then
    KERNEL_CXX="$KERNEL_CXX -fpermissive"
    AC_CACHE_CHECK(FreeBSD version, ac_cv_freebsd_version, [
        save_flags="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS -I$freebsd_includedir"
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/param.h>
#if __FreeBSD_version < 700000
#include <NONEXISTENT_FILE>
#endif]], [[]])], ac_cv_freebsd_version=yes, ac_cv_freebsd_version=no)
        CPPFLAGS="$save_flags"])
    if test $ac_cv_freebsd_version = yes; then
        AC_DEFINE(HAVE_CLICK_BSD_KERNEL)
        AC_DEFINE(HAVE_BSD_POLLING)
    else
        AC_MSG_WARN([
=========================================

Your version of FreeBSD is old.  Click works with FreeBSD 7.x and later.

=========================================])
    fi

    AC_CACHE_CHECK([whether long and int64_t are the same type in the FreeBSD kernel],
        ac_cv_long_64_bsdmodule, [save_flags="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS -I$freebsd_includedir"
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/param.h>
#include <linux/types.h>
void f1(long) {
}
void f1(int64_t) { // will fail if long long and int64_t are the same type
}]], [[]])], ac_cv_long_64_bsdmodule=no, ac_cv_long_64_bsdmodule=yes)])
    if test $ac_cv_long_64_bsdmodule = yes; then
        AC_DEFINE([HAVE_INT64_IS_LONG_BSDMODULE], [1], [Define if 'int64_t' is typedefed to 'long' in bsdmodule.])
    fi

    AC_CACHE_CHECK([whether long long and int64_t are the same type in the FreeBSD kernel],
        ac_cv_long_long_64_bsdmodule, [save_flags="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS -I$freebsd_includedir"
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/param.h>
#include <linux/types.h>
void f1(long long) {
}
void f1(int64_t) { // will fail if long long and int64_t are the same type
}]], [[]])], ac_cv_long_long_64_bsdmodule=no, ac_cv_long_long_64_bsdmodule=yes)])
    if test $ac_cv_long_long_64_bsdmodule = yes; then
        AC_DEFINE([HAVE_INT64_IS_LONG_LONG_BSDMODULE], [1], [Define if 'int64_t' is typedefed to 'long long' in bsdmodule.])
    fi
fi


dnl
dnl more features
dnl

dnl statistics

AC_ARG_ENABLE([stats], [AS_HELP_STRING([--enable-stats[[=LEVEL]]], [enable statistics collection])], :, enable_stats=no)
if test "$enable_stats" = no; then enable_stats=0; fi
if test "$enable_stats" = yes; then enable_stats=1; fi
if test "$enable_stats" -ge 0 > /dev/null 2>&1; then
    AC_DEFINE_UNQUOTED([CLICK_STATS], $enable_stats)
else
    AC_MSG_ERROR([
=========================================

--enable-stats takes an integer, "yes", or "no".

=========================================])
fi

dnl type of scheduling

AC_ARG_ENABLE([stride], [AS_HELP_STRING([--disable-stride], [disable stride scheduler])], :, enable_stride=yes)
if test $enable_stride = yes; then
    AC_DEFINE(HAVE_STRIDE_SCHED)
fi

AC_ARG_ENABLE([task-heap], [AS_HELP_STRING([--enable-task-heap], [use heap for task list])], :, enable_task_heap=no)
if test $enable_task_heap = yes -a $enable_stride = yes; then
    AC_DEFINE(HAVE_TASK_HEAP)
elif test $enable_task_heap = yes; then
        AC_MSG_WARN([
=========================================

Ignoring --enable-task-heap, which is incompatible with --disable-stride.

=========================================])
fi


dnl task statistics
AC_ARG_ENABLE([task-stats],
    [AS_HELP_STRING([--enable-task-stats], [Keep track of task statistics, used for automatic balancing of tasks among threads])],
    [:], [enable_task_stats=no])
if test "x$enable_task_stats" = xyes; then
    AC_DEFINE(HAVE_TASK_STATS)
fi

dnl click load
AC_ARG_ENABLE([cpu-load],
    [AS_HELP_STRING([--enable-cpu-load], [Keep track of CPU usage using an approximation. Useful when using polling keeping the CPU at 100%])],
    [:], [enable_cpu_load=no])
if test "x$enable_cpu_load" = xyes; then
    AC_DEFINE(HAVE_CLICK_LOAD)
else
    if test "x$enable_rsspp" = xyes; then
        AC_MSG_NOTICE([--enable-rsspp needs --enable-cpu-load])
        enable_rsspp=no
    fi
fi

if test "x$enable_rsspp" = xyes; then
    EXTRA_DRIVER_OBJS="nicscheduler.o $EXTRA_DRIVER_OBJS"
else
    enable_rsspp=no
fi

AC_CHECK_FILE($srcdir/include/click/flowruleparser.hh, [ac_have_flow_rule_parser_h=yes], [ac_have_flow_rule_parser_h=no])
AC_CHECK_FILE($srcdir/include/click/flowrulecache.hh, [ac_have_flow_rule_cache_h=yes], [ac_have_flow_rule_cache_h=no])
AC_CHECK_FILE($srcdir/include/click/flowrulemanager.hh, [ac_have_flow_rule_man_h=yes], [ac_have_flow_rule_man_h=no])
if test "x$ac_have_flow_rule_parser_h$ac_have_flow_rule_cache_h$ac_have_flow_rule_man_h$enable_flow_api" = "xyesyesyesyes"; then
    have_flow_api=yes
    AC_DEFINE([HAVE_FLOW_API],1)
    AC_SUBST([HAVE_FLOW_API],1)
else
    have_flow_api=no
    AC_SUBST([HAVE_FLOW_API],0)
fi

dnl debugging malloc

AC_ARG_ENABLE([dmalloc], [AS_HELP_STRING([--enable-dmalloc], [enable debugging malloc])], :, enable_dmalloc=no)
if test $enable_dmalloc = yes; then
    AC_DEFINE([CLICK_DMALLOC], [1], [Define for Click memory allocation debugging.])
fi



dnl debug by tracking hash iterator lifetimes via epoch

AC_ARG_ENABLE([hash-iterator-epochs], [AS_HELP_STRING([--enable-hash-iterator-epochs], [hash iterator epochs])], :, enable_hash_iterator_epochs=no)
if test $enable_hash_iterator_epochs = yes; then
    AC_DEFINE([CLICK_HASH_ITERATOR_EPOCHS], [1], [Define to add epoch tracking to hash iterators])
fi

dnl debug by forcing expensive operations

AC_ARG_ENABLE([force-expensive], [AS_HELP_STRING([--enable-force-expensive], [force expensive packet operations])], :, enable_force_expensive=no)
if test $enable_force_expensive = yes; then
    AC_DEFINE([CLICK_FORCE_EXPENSIVE], [1], [Define for forcing expensive packet operations])
fi


dnl valgrind debugging support

AC_ARG_ENABLE([valgrind], [AS_HELP_STRING([--enable-valgrind], [extra support for debugging with valgrind])], :, enable_valgrind=no)
if test $enable_valgrind = yes; then
    AC_CHECK_HEADERS(valgrind/memcheck.h, ac_found_valgrind_memcheck_h=yes, ac_found_valgrind_memcheck_h=no)
    if test $ac_found_valgrind_memcheck_h = no; then
        AC_MSG_ERROR([
=========================================

Can't find Valgrind header file 'valgrind/memcheck.h'.
Try again without '--enable-valgrind'.

=========================================])
        dnl ' fix syntax highlighting
    fi
    AC_DEFINE([HAVE_VALGRIND], [1], [Define if Click should use Valgrind client requests.])
fi


dnl Click debugging support

AC_ARG_ENABLE([schedule-debugging], [[  --enable-schedule-debugging[=WHAT] enable Click scheduler debugging
                          (no/yes/extra) [yes]]], :, enable_schedule_debugging=no)
value=0
if test "$enable_schedule_debugging" = yes; then
    value=1
elif test "$enable_schedule_debugging" = extra; then
    value=2
fi
if test "$value" != 0; then
    AC_DEFINE_UNQUOTED([CLICK_DEBUG_SCHEDULING], [$value], [Define to enable debugging support for Click scheduling.])
fi

AC_ARG_ENABLE(hash-allocator-poisoning, [  --enable-hash-allocator-poisoning      enable HashAllocator block poisoning], :, enable_hash_allocator_poisoning=no)
if test $enable_hash_allocator_poisoning = yes; then
    AC_DEFINE(HAVE_HASH_ALLOCATOR_POISONING)
fi


dnl Compile for the native architecture
AC_ARG_ENABLE(portable-binary, [AS_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
	acx_maxopt_portable=$enableval, acx_maxopt_portable=no)
if test $acx_maxopt_portable = no; then
    AX_CHECK_COMPILE_FLAG([-march=native], [CXXFLAGS="-march=native $CXXFLAGS";CFLAGS="-march=native $CFLAGS"])
fi

dnl use Intel-specific machine instructions

AC_ARG_ENABLE([intel-cpu], [AS_HELP_STRING([--enable-intel-cpu], [enable Intel-specific machine instructions])], :, enable_intel_cpu=no)
if test $enable_intel_cpu = yes; then
    AC_DEFINE(HAVE_INTEL_CPU)
fi

dnl Support AVX2 instructions

AC_COMPILE_IFELSE([
#ifndef __AVX2__
#error
#endif
         ], [cpu_supports_avx2="yes"], [cpu_supports_avx2="no"])

AC_ARG_ENABLE([avx2],
        AS_HELP_STRING([--disable-avx2],
                   [Do not check whether AVX2 is enabled]),
          [check_avx2=no],
          [check_avx2=yes])

AC_MSG_CHECKING([if AVX2 should be used])
if test "x$cpu_supports_avx2$check_avx2" = "xyesyes"; then
    AC_MSG_RESULT([yes])
    AC_DEFINE([HAVE_AVX2],1)
    save_cflags="$CFLAGS"
    CFLAGS="$save_cflags -mavx2"
    save_cxxflags="$CXXFLAGS"
    CXXFLAGS="$save_cxxflags -mavx2"
else
    AC_MSG_RESULT([no])
fi

AC_COMPILE_IFELSE([
#ifndef __SSE2__
#error
#endif
         ], [cpu_supports_sse2="yes"], [cpu_supports_sse2="no"])
AC_ARG_ENABLE([sse2],
        AS_HELP_STRING([--disable-sse2],
                   [Do not check whether SSE2 is enabled]),
          [check_sse2=no],
          [check_sse2=yes])

AC_MSG_CHECKING([if SSE2 should be used])
if test "x$cpu_supports_sse2$check_sse2" = "xyesyes"; then
    AC_MSG_RESULT([yes])
    AC_DEFINE([HAVE_SSE2],1)
    save_cflags="$CFLAGS"
    CFLAGS="$save_cflags -msse2"
    save_cxxflags="$CXXFLAGS"
    CXXFLAGS="$save_cxxflags -msse2"
else
    AC_MSG_RESULT([no])
fi

AC_COMPILE_IFELSE([
#ifndef __SSE4_2__
#error
#endif
         ], [cpu_supports_sse42="yes"], [cpu_supports_sse42="no"])
AC_ARG_ENABLE([sse42],
        AS_HELP_STRING([--disable-sse42],
                   [Do not check whether SSE4.2 is enabled]),
          [check_sse42=no],
          [check_sse42=yes])

AC_MSG_CHECKING([if SSE4.2 should be used])
if test "x$cpu_supports_sse42$check_sse42" = "xyesyes"; then
    AC_MSG_RESULT([yes])
    AC_DEFINE([HAVE_SSE42],1)
    save_cflags="$CFLAGS"
    CFLAGS="$save_cflags -msse4.2"
    save_cxxflags="$CXXFLAGS"
    CXXFLAGS="$save_cxxflags -msse4.2"
else
    AC_MSG_RESULT([no])
fi



AC_ARG_ENABLE([atomic-builtins],
    [AS_HELP_STRING([--enable-atomic-builtins], [Use GCC builtins atomic functions instead of Click own implementation. It should be always used in non-x86 systems. It requires GCC >= 4.7.0])],
    [:], [enable_atomic_builtins=no])
if test "x${enable_atomic_builtins}" = "xyes"; then
        AC_DEFINE([HAVE_ATOMIC_BUILTINS])
fi

dnl
dnl expand path variables
dnl The "click" versions are expanded versions of the final install locations.
dnl The "clickbuild_" versions are partially expanded versions, with an initial
dnl "clickprefix" replaced by "${clickbuild_prefix}".
dnl Do this here because variables like "CLICKLINUX_FIXINCLUDES_PROGRAM" need
dnl the expanded versions.
dnl

shell_expand () {
    val=`eval echo '$'"$1"`
    while echo "x$val" | grep '\$' >/dev/null 2>&1; do val=`eval echo "$val"`; done
    val=`echo "$val" | sed 's,//*,/,g'`
    eval "$1='$val'"
}

shell_mkbuild () {
    val=`eval echo '$'"$1"`
    pval="$prefix"
    while test -n "$pval" -a -n "$val"; do
        component=`echo "$val" | sed 's,^\(/[[^/]]*\).*,\1,'`
        pcomponent=`echo "$pval" | sed 's,^\(/[[^/]]*\).*,\1,'`
        if test "$component" != "$pcomponent"; then break; fi
        val=`echo "$val" | sed 's,^/[[^/]]*,,'`
        pval=`echo "$pval" | sed 's,^/[[^/]]*,,'`
    done
    while test -n "$pval"; do
        val="/..$val"
        pval=`echo "$pval" | sed 's,^/[[^/]]*,,'`
    done
    eval "clickbuild_$1='"'$'"{clickbuild_prefix}$val'"
}

dnl Preset $prefix and $exec_prefix.
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
clickdir="$DIR"
clickdatadir="$datadir/click"

for i in bin clickdata data dataroot include lib sbin; do
    shell_expand ${i}dir
    shell_mkbuild ${i}dir
done


dnl
dnl kernel interfaces
dnl

AC_CHECK_HEADERS_ONCE([ifaddrs.h linux/ethtool.h linux/sockios.h linux/if_tun.h linux/if_packet.h linux/netlink.h net/if_dl.h net/if_tap.h net/if_tun.h net/if_types.h net/bpf.h netpacket/packet.h])


dnl
dnl possible drivers
dnl

POSSIBLE_DRIVERS=
for i in bsdmodule linuxmodule ns userlevel minios; do
    test -f $srcdir/$i/Makefile.in && POSSIBLE_DRIVERS="$POSSIBLE_DRIVERS $i"
done
AC_SUBST(POSSIBLE_DRIVERS)


dnl
dnl default drivers
dnl

DRIVERS=
AC_SUBST(DRIVERS)

HAVE_USERLEVEL_DRIVER=0
AC_SUBST(HAVE_USERLEVEL_DRIVER)
HAVE_LINUXMODULE_DRIVER=0
AC_SUBST(HAVE_LINUXMODULE_DRIVER)
HAVE_BSDMODULE_DRIVER=0
AC_SUBST(HAVE_BSDMODULE_DRIVER)
HAVE_MINIOS_DRIVER=0
AC_SUBST(HAVE_MINIOS_DRIVER)

OTHER_TARGETS=
AC_SUBST(OTHER_TARGETS)

for i in click-align click-check click-combine click-devirtualize click-fastclassifier click-flatten click-ipopt click-mkmindriver click-pretty click-undead click-xform click2xml; do
    test -d $srcdir/tools/$i && \
        TOOLDIRS="$TOOLDIRS $i" TOOL_TARGETS="$TOOL_TARGETS $i"
done
for i in click-install; do
    test -d $srcdir/tools/$i && TOOLDIRS="$TOOLDIRS $i"
done
AC_SUBST(TOOLDIRS)
AC_SUBST(TOOL_TARGETS)


dnl
dnl DPDK driver
dnl
if test "x$enable_dpdk" != "xno"; then

    AC_MSG_CHECKING([for DPDK library])

    if test "x$enable_dpdk" != "xyes"; then
        RTE_SDK=$enable_dpdk
    fi

    if test -z "$RTE_SDK_BIN"; then
        RTE_SDK_BIN=$RTE_SDK/$RTE_TARGET
    fi

    if test ! -d "$RTE_SDK_BIN"; then
        RTE_SDK_BIN=$RTE_SDK/build/
    fi

    if test -z "$RTE_LIBNAME"; then
        RTE_LIBNAME=dpdk
    fi

    if test -z "$RTE_SRCDIR"; then
        RTE_SRCDIR=$RTE_SDK
    fi

    if test "x$enable_user_multithread" != "xyes"; then
        AC_MSG_ERROR([
=========================================

--enable-dpdk requires --enable-user-multithread which was not provided.

=========================================])
    fi


    if test "x$enable_dpdk" = "xyes" && pkg-config --exists libdpdk; then
      dpdk_sys="meson"
      AC_SUBST(RTE_USE_PKGCONFIG, 1)
      RTE_LIB=$(pkg-config --variable=libdir libdpdk)
      RTE_INCLUDE=$(pkg-config --variable=includedir libdpdk)
      rte_ver_year=`grep "#define RTE_VER_YEAR" "$RTE_INCLUDE/rte_build_config.h" | head -n 1 | awk '{print $3}'`
      rte_ver_month=`grep "#define RTE_VER_MONTH" "$RTE_INCLUDE/rte_build_config.h" | head -n 1 | awk '{print $3}'`
      rte_ver_minor=`grep "#define RTE_VER_MINOR" "$RTE_INCLUDE/rte_build_config.h" | head -n 1 | awk '{print $3}'`
      rte_ver_major=$rte_ver_year

      if test "x$enable_dynamic_linking" = xyes; then
        DPDK_LIBS=$(pkg-config --libs libdpdk)
      else
        DPDK_LIBS=$(pkg-config --libs --static libdpdk)
      fi
	  DPDK_CFLAGS=$(pkg-config --cflags libdpdk)
      AC_MSG_RESULT([yes])
    else
      dpdk_sys="make"
      AC_SUBST(RTE_USE_PKGCONFIG, 0)
      RTE_INCLUDE=${RTE_SDK_BIN}/include/
      RTE_LIB="$RTE_SDK_BIN/lib"
      if test ! -f "$RTE_SDK_BIN/include/rte_eal.h"; then
        AC_MSG_ERROR([
=========================================

Cannot find \$RTE_SDK_BIN/include/rte_eal.h for DPDK.
Define \$RTE_SDK and \$RTE_TARGET as per DPDK documentation,
or install DPDK using meson, or the system package manager.
Note with the system package manager, you need the devel package
version (dpdk-dev or dpdk-devel).

=========================================])
      fi

      AC_MSG_RESULT([yes, found at $RTE_SDK_BIN])

      if test -e "$RTE_SRCDIR/VERSION"; then
        rte_ver_year=`cat $RTE_SRCDIR/VERSION | sed -e 's/-rc/.-rc./' -e 's/$/..99/' | awk -F '.' '{print int($1)}'`
        rte_ver_month=`cat $RTE_SRCDIR/VERSION | sed -e 's/-rc/.-rc./' -e 's/$/..99/' | awk -F '.' '{print int($2)}'`
        rte_ver_minor=`cat $RTE_SRCDIR/VERSION | sed -e 's/-rc/.-rc./' -e 's/$/..99/' | awk -F '.' '{print int($3)}'`
        rte_ver_major=$rte_ver_year
      else
        if grep "#define RTE_VER_MAJOR" "$RTE_SDK_BIN/include/rte_config.h" &> /dev/null; then
            verfile=rte_config
        else
            verfile=rte_version
        fi
        rte_ver_year=`grep "#define RTE_VER_YEAR" "$RTE_SDK_BIN/include/$verfile.h" | head -n 1 | awk '{print $3}'`
        rte_ver_month=`grep "#define RTE_VER_MONTH" "$RTE_SDK_BIN/include/$verfile.h" | head -n 1 | awk '{print $3}'`
        rte_ver_minor=`grep "#define RTE_VER_MINOR" "$RTE_SDK_BIN/include/$verfile.h" | head -n 1 | awk '{print $3}'`
        rte_ver_major=`grep "#define RTE_VER_MAJOR" "$RTE_SDK_BIN/include/$verfile.h" | head -n 1 | awk '{print $3}'`
      fi
      dpdk_vars=`cd userlevel/dpdk/ && make -s RTE_SDK=$RTE_SDK RTE_TARGET=$RTE_TARGET RTE_VER_YEAR=$rte_ver_year RTE_VER_MONTH=$rte_ver_month RTE_VER_MAJOR=$rte_ver_major RTE_VER_MINOR=$rte_ver_minor`
      eval $dpdk_vars
    fi

    AC_SUBST(RTE_SDK)
    AC_SUBST(RTE_TARGET)
    AC_SUBST(RTE_SDK_BIN)
    AC_SUBST(RTE_VER_YEAR,  $rte_ver_year)
    AC_SUBST(RTE_VER_MONTH, $rte_ver_month)
    AC_SUBST(RTE_VER_MAJOR, $rte_ver_major)
    AC_SUBST(RTE_VER_MINOR, $rte_ver_minor)
    AC_SUBST(DPDK_INCLUDES, -I${RTE_INCLUDE})
    AC_SUBST(DPDK_LIBS, ${DPDK_LIBS})
    AC_SUBST(DPDK_CFLAGS, ${DPDK_CFLAGS})

    AC_DEFINE([HAVE_DPDK])
    AC_SUBST(USE_DPDK, yes)

    AC_MSG_CHECKING([whether DPDK has rte_eth_read_clock])
    if ${READELF} -Ws "$RTE_LIB/librte_ethdev.a" | grep rte_eth_read_clock &> /dev/null; then
      AC_MSG_RESULT([yes])
      AC_DEFINE([HAVE_DPDK_READ_CLOCK])
    else
      AC_MSG_RESULT([no])
    fi    
   
    AC_MSG_CHECKING([whether DPDK has rte_flow_update])
    if ${READELF} -Ws "$RTE_LIB/librte_ethdev.a" | grep rte_flow_update &> /dev/null; then
      AC_MSG_RESULT([yes])
      AC_DEFINE([HAVE_RTE_FLOW_UPDATE])
    else
      AC_MSG_RESULT([no])
    fi

fi

if test "x$enable_dpdk_pool" = xyes; then
    if test "x$enable_dpdk" = "xno"; then
        AC_MSG_ERROR([
=========================================

--enable-dpdk-pool requires --enable-dpdk which was not provided.

=========================================])
    fi
    AC_DEFINE([HAVE_DPDK_PACKET_POOL])
fi

if test "x$enable_dpdk_xchg" = "xyes"; then
    if test "x$enable_dpdk" = "xno"; then
        AC_MSG_ERROR([
=========================================

--enable-dpdk-xchg requires --enable-dpdk which was not provided.

=========================================])
    fi
    AC_DEFINE([HAVE_DPDK_XCHG])
    AC_SUBST(HAVE_DPDK_XCHG,y)
    AC_SUBST(DPDK_LIBS,$(echo "$DPDK_LIBS" | sed -e "s/-lrte_xchg_mbuf//"))
    EXTRA_DRIVER_OBJS="$EXTRA_DRIVER_OBJS fromdpdkdevicexchg.o todpdkdevicexchg.o"
fi

if test "x$enable_dpdk_packet" = "xyes"; then
    if test "x$enable_dpdk" = "xno"; then
        AC_MSG_ERROR([
=========================================

--enable-dpdk-packet requires --enable-dpdk which was not provided.

=========================================])
    fi
    AC_DEFINE([CLICK_PACKET_USE_DPDK])
fi


dnl pcap library
dnl note: no longer need pcap under Linux

if test "$enable_userlevel" = yes; then
    CLICK_CHECK_LIBPCAP
    CLICK_CHECK_NUMA
    CLICK_CHECK_NETMAP

    if test "$HAVE_PCAP" != yes -a "$HAVE_NETMAP" != yes -a "$ac_cv_under_linux" != yes; then
        AC_MSG_WARN([
=========================================

pcap.h and/or -lpcap not found; user-level driver can't steal packets.

=========================================])
        dnl ' fix syntax highlighting
    fi
    DRIVERS="$DRIVERS userlevel"
    AC_DEFINE(HAVE_USERLEVEL_DRIVER)
    HAVE_USERLEVEL_DRIVER=1
fi

if test "x$enable_dpdk_packet" = "xyes" -a "x$HAVE_NETMAP" = "xyes"; then
        AC_MSG_ERROR([--with-netmap is not compatible with --enable-dpdk-packet ])
fi

if test "x$enable_netmap_pool" = "xyes"; then
    if test "x$HAVE_NETMAP" != "xyes"; then
        AC_MSG_ERROR([
=========================================

--enable-netmap-pool requires --with-netmap which was not provided.

=========================================])
    fi
    if test "x$enable_zerocopy" != "xyes"; then
        AC_MSG_ERROR([
=========================================

--enable-netmap-pool requires --enable-zerocopy which was not provided.

=========================================])
    fi
    AC_DEFINE([HAVE_NETMAP_PACKET_POOL])
    AC_SUBST(HAVE_NETMAP_PACKET_POOL, yes)
fi

dnl other user-level specifics

AC_CACHE_CHECK([whether struct if_data has ifi_datalen], [ac_cv_if_data_ifi_datalen],
    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <net/if.h>
#include <net/if_var.h>
]], [[struct if_msghdr ifm; ifm.ifm_data.ifi_datalen = 0;]])], ac_cv_if_data_ifi_datalen=yes, ac_cv_if_data_ifi_datalen=no)])
if test "x$ac_cv_if_data_ifi_datalen" = xyes; then
    AC_DEFINE([HAVE_IF_DATA_IFI_DATALEN], [1], [Define if 'struct if_data' has an 'ifi_datalen' member.])
fi

AC_CACHE_CHECK([whether struct sockaddr_in has sin_len], [ac_cv_sockaddr_in_sin_len],
    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>
#include <netinet/in.h>
]], [[struct sockaddr_in sin; sin.sin_len = 0;]])], ac_cv_sockaddr_in_sin_len=yes, ac_cv_sockaddr_in_sin_len=no)])
if test "x$ac_cv_sockaddr_in_sin_len" = xyes; then
    AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN], [1], [Define if 'struct sockaddr_in' has a 'sin_len' member.])
fi


dnl PlanetLab "Privileged Operations" library

explicit_proper=yes
AC_ARG_WITH(proper, [[  --with-proper[=PREFIX]  use PlanetLab Proper library (optional)]],
  [properprefix=$withval; if test -z "$withval" -o "$withval" = yes; then properprefix=; fi],
  [properprefix=no; explicit_proper=no])
if test "$properprefix" != no; then
    saveflags="$CPPFLAGS"; test -n "$properprefix" && CPPFLAGS="$CPPFLAGS -I$properprefix/include"
    AC_CHECK_HEADER(prop.h, have_prop_h=yes, have_prop_h=no)
    CPPFLAGS="$saveflags"

    AC_LANG([C])
    saveflags="$LDFLAGS"; test -n "$properprefix" && LDFLAGS="$LDFLAGS -L$properprefix/lib"
    AC_CHECK_LIB(proper, prop_open, have_libproper=yes, have_libproper=no)
    LDFLAGS="$saveflags"
    AC_LANG([C++])

    if test $have_prop_h = yes -a $have_libproper = yes; then
        AC_DEFINE(HAVE_PROPER)
        test -n "$properprefix" && PROPER_INCLUDES="-I$properprefix/include" && PROPER_LIBS="-L$properprefix/lib"
        PROPER_LIBS="$PROPER_LIBS -lproper"
    elif test $explicit_proper = yes; then
        PROPER_INCLUDES= PROPER_LIBS=
        AC_MSG_ERROR([
=========================================

You explicitly specified --with-proper, but the proper headers and/or
libraries are not where you said they would be.  Run again supplying
--without-proper or --with-proper=PREFIX.

=========================================])
    fi
fi
AC_SUBST(PROPER_INCLUDES)
AC_SUBST(PROPER_LIBS)


dnl expat library

explicit_expat=yes
AC_ARG_WITH(expat, [[  --with-expat[=PREFIX]   locate expat XML library (optional)]],
  [expatprefix=$withval; if test -z "$withval" -o "$withval" = yes; then expatprefix=; fi],
  expatprefix=; explicit_expat=no)

XML2CLICK=
if test "$expatprefix" != no; then
    saveflags="$CPPFLAGS"; test -n "$expatprefix" && CPPFLAGS="$CPPFLAGS -I$expatprefix/include"
    AC_CHECK_HEADER(expat.h, have_expat_h=yes, have_expat_h=no)
    CPPFLAGS="$saveflags"

    AC_LANG([C])
    saveflags="$LDFLAGS"; test -n "$expatprefix" && LDFLAGS="$LDFLAGS -L$expatprefix/lib"
    AC_CHECK_LIB(expat, XML_ParserCreateNS, have_libexpat=yes, have_libexpat=no)
    LDFLAGS="$saveflags"

    if test $have_expat_h = yes -a $have_libexpat = yes; then
        AC_DEFINE(HAVE_EXPAT)
        XML2CLICK=xml2click
        test -n "$expatprefix" && EXPAT_INCLUDES="-I$expatprefix/include" && EXPAT_LIBS="-L$expatprefix/lib"
        EXPAT_LIBS="$EXPAT_LIBS -lexpat"
    elif test $explicit_expat = yes; then
        EXPAT_INCLUDES= EXPAT_LIBS=
        AC_MSG_ERROR([
=========================================

You explicitly specified --with-expat, but the expat headers and/or libraries
are not where you said they would be.  Run again supplying --without-expat
or --with-expat=PREFIX.

=========================================])
    fi
fi
AC_SUBST(XML2CLICK)
AC_SUBST(EXPAT_INCLUDES)
AC_SUBST(EXPAT_LIBS)


dnl check linuxmodule for Linux

if test $ac_have_linux_kernel = y; then

    save_cc="$CC"
    save_cxx="$CXX"
    save_cppflags="$CPPFLAGS"
    save_cflags="$CFLAGS"
    save_cxxflags="$CXXFLAGS"
    unset -v CFLAGS CPPFLAGS
    CC="$KERNEL_CC"
    CXX="$KERNEL_CXX"
    CXXFLAGS="$KERNEL_CXXFLAGS"

    dnl check for arguments to pass to Linux make
    linux_makeargs=
    if test -n "$ARCH"; then
        linux_makeargs="$linux_makeargs ARCH=$ARCH"
    fi
    if test -n "$CROSS_COMPILE"; then
        linux_makeargs="$linux_makeargs CROSS_COMPILE=$CROSS_COMPILE"
    elif test -n "$ac_tool_prefix"; then
        linux_makeargs="$linux_makeargs CROSS_COMPILE=$ac_tool_prefix"
    fi
    AC_SUBST(linux_makeargs)

    dnl check for Linux #includes
    LINUX_DEBUG_FLAGS=
    if test -n "$LINUX_CFLAGS"; then
        :
    elif test $LINUXMODULE_2_6 = 1; then
        AC_MSG_CHECKING([for Linux kernel compilation flags])
        echo >conftest.c
        make -C $linux_builddir M="`pwd`" $linux_makeargs --no-print-directory -p conftest.o >conftest.dat 2>&1
        for v in KBUILD_CPPFLAGS KBUILD_CFLAGS CPPFLAGS CFLAGS LINUXINCLUDE debug_flags; do
            eval l$v="'""`grep ^$v' *:*=' conftest.dat | sed s/^$v' *:*= *//'`""'"
        done
        if test -z "$lKBUILD_CPPFLAGS$lKBUILD_CFLAGS$lCPPFLAGS$lCFLAGS$lLINUXINCLUDE"; then
            AC_MSG_RESULT([not found])
            AC_MSG_ERROR([
==============================================

Can't find Linux compilation flags.

==============================================])
            dnl ' fix syntax highlighting
        fi
        echo "$lCPPFLAGS $lCFLAGS $lLINUXINCLUDE $lKBUILD_CPPFLAGS $lKBUILD_CFLAGS" >conftest.dat
        LINUX_CFLAGS="`sed -e s,-Wno-pointer-sign,,g \
            -e s,-fno-unit-at-a-time,,g \
            -e s,-Wstrict-prototypes,,g \
            -e s,-Wdeclaration-after-statement,,g \
            -e s,-fno-common,,g \
            -e 's,-std=[[-a-z0-9+]]*,,g' \
            -e s,-Werror-implicit-function-declaration,,g \
            -e 's,-W[[^ ]]*,,g' <conftest.dat`"
        AC_MSG_RESULT($LINUX_CFLAGS)
        LINUX_DEBUG_FLAGS="$ldebug_flags"
    fi

    LINUX_FIXINCLUDES_PROGRAM=
    CLICKLINUX_FIXINCLUDES_PROGRAM=
    if test "$LINUXMODULE_FIXINCLUDES" = 1; then
        AC_MSG_NOTICE([making C++-safe versions of Linux kernel headers (may take a while)])
        mydir="`pwd`"
        mysrcdir="$srcdir"
        if expr $mysrcdir : / >/dev/null; then :; else mysrcdir="$mydir/$srcdir"; fi
        (cd $linux_builddir; $mysrcdir/linuxmodule/click-linuxtool.pl -o "$mydir/include/click-linuxmodule" $LINUX_CFLAGS) >conftest.dat
        if test $? != 0; then
            AC_MSG_ERROR([
==============================================

click-linuxtool.pl execution failed.

==============================================])
        fi
        LINUX_CFLAGS="`head -n 1 conftest.dat`"
        LINUX_FIXINCLUDES_PROGRAM="| sed `tail -n 1 conftest.dat`"
        CLICKLINUX_FIXINCLUDES_PROGRAM="| sed `tail -n 1 conftest.dat | sed -e "s$tabchar$mydir/include/click-linuxmodule$tabchar$clickbuild_includedir/click-linuxmodule${tabchar}g"`"
    fi
    AC_SUBST([LINUX_FIXINCLUDES_PROGRAM])
    AC_SUBST([CLICKLINUX_FIXINCLUDES_PROGRAM])
    AC_SUBST([LINUX_DEBUG_FLAGS])


    # -w inhibits warning messages to make debugging actual errors easier
    echo "$save_cppflags $LINUX_CFLAGS -w" >conftest.dat
    CPPFLAGS="`sed -e s,-Werror=strict-prototypes,, <conftest.dat`"


    # CLICK_LINUXMODULE_PROLOGUE()
    linux_autoconf_include=
    if test "$linux_version_code" -lt 132638; then
        AC_DEFINE([HAVE_CHECK_AUTOCONF_INCLUDED], [1], [Define if the AUTOCONF_INCLUDED symbol should be checked.])
        linux_autoconf_include="#if !defined(AUTOCONF_INCLUDED)
# include <linux/autoconf.h>
#endif
"
    fi
    AC_DEFUN([CLICK_LINUXMODULE_PROLOGUE], [[#define KBUILD_STR(s) #s
#define KBUILD_BASENAME KBUILD_STR(click)
#define KBUILD_MODNAME KBUILD_STR(click)
#define new linux_new
#define this linux_this
#define delete linux_delete
#define class linux_class
#define virtual linux_virtual
#define typename linux_typename
#define protected linux_protected
#define public linux_public
#define namespace linux_namespace
#define false linux_false
#define true linux_true
#define CLICK_CXX_PROTECTED 1
$linux_autoconf_include
#include <asm/types.h>]])


    AC_CACHE_CHECK([for C++-includable kernel header files], [ac_cv_cxx_aware_system],
        [AC_LANG([C++])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/signal.h>
#include <linux/skbuff.h>
#include <linux/sched.h>]], [[return 0]])], ac_cv_cxx_aware_system=yes, ac_cv_cxx_aware_system=no)
        ])

    if test $ac_cv_cxx_aware_system = yes; then
        DRIVERS="$DRIVERS linuxmodule"
        TOOL_TARGETS="$TOOL_TARGETS click-install"
        AC_DEFINE(HAVE_LINUXMODULE_DRIVER)
        HAVE_LINUXMODULE_DRIVER=1
    elif test x$enable_linuxmodule_default = xyes; then
        AC_MSG_WARN([
=========================================

Your Linux kernel header files cause errors when included by a C++ program,
so I won't try to compile the linuxmodule driver.

Click modifies the Linux kernel's header files to make them work with
C++, using the program 'linuxmodule/click-linuxtool.pl'. It looks like
your kernel header files have features the tool doesn't know how to fix.
You can report this error to us via a Github issue, or, even better,
try to fix the error. See the config.log file for more information on the
error.

=========================================])
        dnl ' fix syntax highlighting
    else
        AC_MSG_ERROR([
=========================================

Your Linux kernel header files cause errors when included by a C++ program.

Click modifies the Linux kernel's header files to make them work with
C++, using the program 'linuxmodule/click-linuxtool.pl'. It looks like
your kernel header files have features that tool doesn't know how to fix.
You can report this error to us on the Click mailing list, or, even better,
try to fix the error. See the config.log file for more information on the
error.

=========================================])
    fi

    # remove -w
    echo "$save_cppflags $LINUX_CFLAGS" >conftest.dat
    CPPFLAGS="`sed -e s,-Werror=strict-prototypes,,g <conftest.dat`"

    if test $ac_cv_cxx_aware_system = yes; then


    dnl Linux kernel basic types

    AC_CACHE_CHECK([whether long and int64_t are the same type in the Linux kernel],
        ac_cv_long_64_linuxmodule, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/types.h>
void f1(long) {
}
void f1(int64_t) { // will fail if long and int64_t are the same type
}]], [[]])], ac_cv_long_64_linuxmodule=no, ac_cv_long_64_linuxmodule=yes)])
    if test $ac_cv_long_64_linuxmodule = yes; then
        AC_DEFINE([HAVE_INT64_IS_LONG_LINUXMODULE], [1], [Define if 'int64_t' is typedefed to 'long' in linuxmodule.])
    fi

    AC_CACHE_CHECK([whether long long and int64_t are the same type in the Linux kernel],
        ac_cv_long_long_64_linuxmodule, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/types.h>
void f1(long long) {
}
void f1(int64_t) { // will fail if long long and int64_t are the same type
}]], [[]])], ac_cv_long_long_64_linuxmodule=no, ac_cv_long_long_64_linuxmodule=yes)])
    if test $ac_cv_long_long_64_linuxmodule = yes; then
        AC_DEFINE([HAVE_INT64_IS_LONG_LONG_LINUXMODULE], [1], [Define if 'int64_t' is typedefed to 'long long' in linuxmodule.])
    fi

    AC_CACHE_CHECK([whether uintptr_t is defined in the Linux kernel],
        ac_cv_uintptr_t_linuxmodule, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/types.h>
]], [[uintptr_t i = 0;]])], ac_cv_uintptr_t_linuxmodule=yes, ac_cv_uintptr_t_linuxmodule=no)])
    if test $ac_cv_uintptr_t_linuxmodule = yes; then
        AC_DEFINE([HAVE_UINTPTR_T_LINUXMODULE], [1], [Define to 1 if Linux defines the type 'uintptr_t'.])
    fi


    dnl Linux kernel basic configuration

    AC_CHECK_DECL(atomic_cmpxchg, [ac_cv_linux_atomic_cmpxchg=yes], [ac_cv_linux_atomic_cmpxchg=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <asm/atomic.h>]])
    if test $ac_cv_linux_atomic_cmpxchg = yes; then
        AC_DEFINE([HAVE_LINUX_ATOMIC_CMPXCHG], [1], [Define if your Linux kernel architecture defines atomic_cmpxchg.])
    fi

    AC_CHECK_DECL(atomic_set_mask, [ac_cv_linux_atomic_set_mask=yes], [ac_cv_linux_atomic_set_mask=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <asm/atomic.h>]])
    if test $ac_cv_linux_atomic_set_mask = yes; then
        AC_DEFINE([HAVE_LINUX_ATOMIC_SET_MASK], [1], [Define if your Linux kernel architecture defines atomic_set_mask.])
    fi

    AC_CHECK_DECL(atomic_add_return, [ac_cv_linux_atomic_add_return=yes], [ac_cv_linux_atomic_add_return=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <asm/atomic.h>]])
    if test $ac_cv_linux_atomic_add_return = yes; then
        AC_DEFINE([HAVE_LINUX_ATOMIC_ADD_RETURN], [1], [Define if your Linux kernel architecture defines atomic_add_return.])
    fi

    AC_CACHE_CHECK([for <asm/alternative.h>], [ac_cv_linux_asm_alternative_h],
        [AC_LANG([C])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <asm/alternative.h>]],
[[]])],
        [ac_cv_linux_asm_alternative_h=yes], [ac_cv_linux_asm_alternative_h=no])])
    if test $ac_cv_linux_asm_alternative_h = yes; then
        AC_DEFINE([HAVE_LINUX_ASM_ALTERNATIVE_H], [1], [Define if you have the <asm/alternative.h> header file.])
    fi

    AC_CACHE_CHECK([for <asm/scatterlist.h>], [ac_cv_linux_asm_scatterlist_h],
        [AC_LANG([C])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <asm/scatterlist.h>]],
[[]])],
        [ac_cv_linux_asm_scatterlist_h=yes], [ac_cv_linux_asm_scatterlist_h=no])])
    if test $ac_cv_linux_asm_scatterlist_h = yes; then
        AC_DEFINE([HAVE_LINUX_ASM_SCATTERLIST_H], [1], [Define if you have the <asm/scatterlist.h> header file.])
    fi

    AC_CACHE_CHECK([for <asm/system.h>], [ac_cv_linux_asm_system_h],
        [AC_LANG([C])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <asm/system.h>]],
[[]])],
        [ac_cv_linux_asm_system_h=yes], [ac_cv_linux_asm_system_h=no])])
    if test $ac_cv_linux_asm_system_h = yes; then
        AC_DEFINE([HAVE_LINUX_ASM_SYSTEM_H], [1], [Define if you have the <asm/system.h> header file.])
    fi

    AC_CHECK_DECL([set_cpus_allowed_ptr], [ac_cv_linux_set_cpus_allowed_ptr=yes], [ac_cv_linux_set_cpus_allowed_ptr=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/sched.h>]])
    if test $ac_cv_linux_set_cpus_allowed_ptr = yes; then
        AC_DEFINE([HAVE_LINUX_SET_CPUS_ALLOWED_PTR], [1], [Define if your Linux kernel has set_cpus_allowed_ptr.])
    fi


    dnl Linux kernel network configuration

    AC_LANG([C++])
    AC_CACHE_CHECK([whether struct sk_buff has a security member], [ac_cv_linuxmodule_skbuff_security],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; s->security = 0;]])],
        [ac_cv_linuxmodule_skbuff_security=yes], [ac_cv_linuxmodule_skbuff_security=no])])
    if test $ac_cv_linuxmodule_skbuff_security = yes; then
        AC_DEFINE([HAVE_LINUX_SKBUFF_SECURITY], [1], [Define if 'struct sk_buff' has a 'security' member.])
    fi

    AC_CACHE_CHECK([whether struct sk_buff has an fclone member], [ac_cv_linuxmodule_skbuff_fclone],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; s->fclone = 0;]])],
        [ac_cv_linuxmodule_skbuff_fclone=yes], [ac_cv_linuxmodule_skbuff_fclone=no])])
    if test $ac_cv_linuxmodule_skbuff_fclone = yes; then
        AC_DEFINE([HAVE_LINUX_SKBUFF_FCLONE], [1], [Define if 'struct sk_buff' has an 'fclone' member.])
    fi

    AC_CACHE_CHECK([whether skb_shinfo has a tso_size member], [ac_cv_linuxmodule_skb_shinfo_tso_size],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; skb_shinfo(s)->tso_size = 0;]])],
        [ac_cv_linuxmodule_skb_shinfo_tso_size=yes], [ac_cv_linuxmodule_skb_shinfo_tso_size=no])])
    if test $ac_cv_linuxmodule_skb_shinfo_tso_size = yes; then
        AC_DEFINE([HAVE_LINUX_SKB_SHINFO_TSO_SIZE], [1], [Define if 'struct skb_shared_info' has a 'tso_size' member.])
    fi

    AC_CACHE_CHECK([whether skb_shinfo has a gso_size member], [ac_cv_linuxmodule_skb_shinfo_gso_size],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; skb_shinfo(s)->gso_size = 0;]])],
        [ac_cv_linuxmodule_skb_shinfo_gso_size=yes], [ac_cv_linuxmodule_skb_shinfo_gso_size=no])])
    if test $ac_cv_linuxmodule_skb_shinfo_gso_size = yes; then
        AC_DEFINE([HAVE_LINUX_SKB_SHINFO_GSO_SIZE], [1], [Define if 'struct skb_shared_info' has a 'gso_size' member.])
    fi

    AC_CACHE_CHECK([whether skb_shinfo has a ufo_size member], [ac_cv_linuxmodule_skb_shinfo_ufo_size],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; skb_shinfo(s)->ufo_size = 0;]])],
        [ac_cv_linuxmodule_skb_shinfo_ufo_size=yes], [ac_cv_linuxmodule_skb_shinfo_ufo_size=no])])
    if test $ac_cv_linuxmodule_skb_shinfo_ufo_size = yes; then
        AC_DEFINE([HAVE_LINUX_SKB_SHINFO_UFO_SIZE], [1], [Define if 'struct skb_shared_info' has a 'ufo_size' member.])
    fi

    AC_CACHE_CHECK([whether skb_shinfo has an ip6_frag_id member], [ac_cv_linuxmodule_skb_shinfo_ip6_frag_id],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; skb_shinfo(s)->ip6_frag_id = 0;]])],
        [ac_cv_linuxmodule_skb_shinfo_ip6_frag_id=yes], [ac_cv_linuxmodule_skb_shinfo_ip6_frag_id=no])])
    if test $ac_cv_linuxmodule_skb_shinfo_ip6_frag_id = yes; then
        AC_DEFINE([HAVE_LINUX_SKB_SHINFO_IP6_FRAG_ID], [1], [Define if 'struct skb_shared_info' has an 'ip6_frag_id' member.])
    fi

    AC_CACHE_CHECK([whether skb_shinfo has tx_flags defining SKBTX_DEV_ZEROCOPY], [ac_cv_linuxmodule_skb_shinfo_tx_flags_skbtx_dev_zerocopy],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; skb_shinfo(s)->tx_flags = SKBTX_DEV_ZEROCOPY;]])],
        [ac_cv_linuxmodule_skb_shinfo_tx_flags_skbtx_dev_zerocopy=yes], [ac_cv_linuxmodule_skb_shinfo_tx_flags_skbtx_dev_zerocopy=no])])
    if test $ac_cv_linuxmodule_skb_shinfo_tx_flags_skbtx_dev_zerocopy = yes; then
        AC_DEFINE([HAVE_LINUX_SKB_SHINFO_TX_FLAGS_SKBTX_DEV_ZEROCOPY], [1], [Define if 'struct skb_shared_info' has a 'tx_flags' member defining 'SKBTX_DEV_ZEROCOPY'.])
    fi

    AC_CACHE_CHECK([whether skb_shinfo has a tx_flags union], [ac_cv_linuxmodule_skb_shinfo_tx_flags_union],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *s; skb_shinfo(s)->tx_flags.flags = 0;]])],
        [ac_cv_linuxmodule_skb_shinfo_tx_flags_union=yes], [ac_cv_linuxmodule_skb_shinfo_tx_flags_union=no])])
    if test $ac_cv_linuxmodule_skb_shinfo_tx_flags_union = yes; then
        AC_DEFINE([HAVE_LINUX_SKB_SHINFO_TX_FLAGS_UNION], [1], [Define if 'struct skb_shared_info' has a 'tx_flags.flags' member.])
    fi

    AC_CACHE_CHECK([for device polling kernel extension], [ac_cv_linuxmodule_net_device_polling],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/netdevice.h>]],
[[extern struct net_device *d; d->polling = 0;]])],
        [ac_cv_linuxmodule_net_device_polling=yes], [ac_cv_linuxmodule_net_device_polling=no])])
    if test $ac_cv_linuxmodule_net_device_polling = yes; then
        AC_DEFINE([HAVE_LINUX_POLLING], [1], [Define if your Linux kernel has polling extensions.])
    fi

    AC_CHECK_DECL([skb_dst_drop], [ac_cv_skb_dst_drop=yes], [ac_cv_skb_dst_drop=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <net/dst.h>]])
    if test $ac_cv_skb_dst_drop = yes; then
        AC_DEFINE([HAVE_SKB_DST_DROP], [1], [Define if you have the skb_dst_drop function.])
    fi

    AC_CHECK_DECL([skb_recycle], [ac_cv_skb_recycle=yes], [ac_cv_skb_recycle=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]])
    if test $ac_cv_skb_recycle = yes; then
        AC_DEFINE([HAVE_SKB_RECYCLE], [1], [Define if you have the skb_recycle function.])
    fi

    AC_CHECK_DECL([skb_recycle_check], [ac_cv_skb_recycle_check=yes], [ac_cv_skb_recycle_check=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]])
    if test $ac_cv_skb_recycle_check = yes; then
        AC_DEFINE([HAVE_SKB_RECYCLE_CHECK], [1], [Define if you have the skb_recycle_check function.])
    fi

save_cflags="$CFLAGS"
CFLAGS="$save_cflags -Werror-implicit-function-declaration"

    AC_CACHE_CHECK([whether skb_recycle returns an sk_buff], [ac_cv_linuxmodule_click_skb_recycle],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]],
[[extern struct sk_buff *b; b = skb_recycle(b);]])],
        [ac_cv_linuxmodule_click_skb_recycle=yes], [ac_cv_linuxmodule_click_skb_recycle=no])])
    if test $ac_cv_linuxmodule_click_skb_recycle = yes; then
        AC_DEFINE([HAVE_CLICK_SKB_RECYCLE], [1], [Define if your Linux kernel has Click skb_recycle.])
    fi

CFLAGS="$save_cflags"

    AC_CHECK_DECL(skb_linearize, [ac_cv_skb_linearize=yes], [ac_cv_skb_linearize=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>]])
    if test $ac_cv_skb_linearize = yes; then
        AC_DEFINE([HAVE_SKB_LINEARIZE], [1], [Define if you have the skb_linearize function.])
    fi

    AC_CACHE_CHECK([whether netif_receive_skb has been extended], [ac_cv_linuxmodule_netif_receive_skb_extended],
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/netdevice.h>]],
[[netif_receive_skb(0, 0, 0);]])],
        [ac_cv_linuxmodule_netif_receive_skb_extended=yes], [ac_cv_linuxmodule_netif_receive_skb_extended=no])])
    if test $ac_cv_linuxmodule_netif_receive_skb_extended = yes; then
        AC_DEFINE([HAVE_NETIF_RECEIVE_SKB_EXTENDED], [1], [Define if netif_receive_skb takes 3 arguments.])
    fi

    AC_CHECK_DECL(net_enable_timestamp, [ac_cv_net_enable_timestamp=yes], [ac_cv_net_enable_timestamp=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>
#include <linux/netdevice.h>]])
    if test $ac_cv_net_enable_timestamp = yes; then
        AC_DEFINE([HAVE_NET_ENABLE_TIMESTAMP], [1], [Define if you have the net_enable_timestamp function.])
    fi

    AC_CHECK_DECL(netif_tx_lock, [ac_cv_netif_tx_lock=yes], [ac_cv_netif_tx_lock=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>
#include <linux/netdevice.h>]])
    if test $ac_cv_netif_tx_lock = yes; then
        AC_DEFINE([HAVE_NETIF_TX_LOCK], [1], [Define if you have the netif_tx_lock function.])
    fi

    AC_CHECK_DECL(netdev_get_tx_queue, [ac_cv_netdev_get_tx_queue=yes], [ac_cv_netdev_get_tx_queue=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>
#include <linux/netdevice.h>]])
    if test $ac_cv_netdev_get_tx_queue = yes; then
        AC_DEFINE([HAVE_NETDEV_GET_TX_QUEUE], [1], [Define if you have the netdev_get_tx_queue function.])
    fi

    AC_CHECK_DECL(netif_tx_queue_frozen, [ac_cv_netif_tx_queue_frozen=yes], [ac_cv_netif_tx_queue_frozen=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>
#include <linux/netdevice.h>]])
    if test $ac_cv_netif_tx_queue_frozen = yes; then
        AC_DEFINE([HAVE_NETIF_TX_QUEUE_FROZEN], [1], [Define if you have the netif_tx_queue_frozen function.])
    fi

    AC_CHECK_DECL(netdev_uses_dsa_tags, [ac_cv_netdev_uses_dsa_tags=yes], [ac_cv_netdev_uses_dsa_tags=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>
#include <linux/netdevice.h>]])
    if test $ac_cv_netdev_uses_dsa_tags = yes; then
        AC_DEFINE([HAVE_NETDEV_USES_DSA_TAGS], [1], [Define if you have the netdev_uses_dsa_tags function.])
    fi

    AC_CHECK_DECL(netdev_uses_trailer_tags, [ac_cv_netdev_uses_trailer_tags=yes], [ac_cv_netdev_uses_trailer_tags=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/skbuff.h>
#include <linux/netdevice.h>]])
    if test $ac_cv_netdev_uses_trailer_tags = yes; then
        AC_DEFINE([HAVE_NETDEV_USES_TRAILER_TAGS], [1], [Define if you have the netdev_uses_trailer_tags function.])
    fi

    AC_CACHE_CHECK(for netdev_rx_handler_register kernel symbol, ac_cv_linux_netdev_rx_handler_register,
    [if grep "__ksymtab_netdev_rx_handler_register" $linux_system_map >/dev/null 2>&1; then
        ac_cv_linux_netdev_rx_handler_register=yes
    else ac_cv_linux_netdev_rx_handler_register=no; fi])
    if test $ac_cv_linux_netdev_rx_handler_register = yes; then
        AC_DEFINE(HAVE_LINUX_NETDEV_RX_HANDLER_REGISTER)
    fi


    dnl Linux kernel time configuration

    AC_CACHE_CHECK([for get_monotonic_coarse kernel symbol], [ac_cv_linux_get_monotonic_coarse],
    [if grep '__ksymtab_get_monotonic_coarse$' $linux_system_map >/dev/null 2>&1; then
        ac_cv_linux_get_monotonic_coarse=yes
    else ac_cv_linux_get_monotonic_coarse=no; fi])
    if test $ac_cv_linux_get_monotonic_coarse = yes; then
        AC_DEFINE(HAVE_LINUX_GET_MONOTONIC_COARSE)
    fi

    AC_CACHE_CHECK([for ktime_mono_to_any kernel symbol], [ac_cv_linux_ktime_mono_to_any],
    [if grep '__ksymtab_ktime_mono_to_any$' $linux_system_map >/dev/null 2>&1; then
        ac_cv_linux_ktime_mono_to_any=yes
    else ac_cv_linux_ktime_mono_to_any=no; fi])
    if test $ac_cv_linux_ktime_mono_to_any = yes; then
        AC_DEFINE(HAVE_LINUX_KTIME_MONO_TO_ANY)
    fi

    AC_CACHE_CHECK([for getboottime kernel symbol], [ac_cv_linux_getboottime],
    [if grep "__ksymtab_getboottime" $linux_system_map >/dev/null 2>&1; then
        ac_cv_linux_getboottime=yes
    else ac_cv_linux_getboottime=no; fi])
    if test $ac_cv_linux_getboottime = yes; then
        AC_DEFINE(HAVE_LINUX_GETBOOTTIME)
    fi


    dnl Linux kernel file system configuration

    AC_CACHE_CHECK([whether struct super_block has an s_d_op member], [ac_cv_linuxmodule_super_block_s_d_op],
        [AC_LANG([C])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/fs.h>]],
[[extern struct super_block *sb; sb->s_d_op = 0;]])],
        [ac_cv_linuxmodule_super_block_s_d_op=yes], [ac_cv_linuxmodule_super_block_s_d_op=no])])
    if test $ac_cv_linuxmodule_super_block_s_d_op = yes; then
        AC_DEFINE([HAVE_LINUX_SUPER_BLOCK_S_D_OP], [1], [Define if 'struct super_block' has an 's_d_op' member.])
    fi

    AC_CHECK_DECL([d_make_root], [ac_cv_linux_d_make_root=yes], [ac_cv_linux_d_make_root=no], [CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/fs.h>
#include <linux/dcache.h>]])
    if test $ac_cv_linux_d_make_root = yes; then
        AC_DEFINE([HAVE_LINUX_D_MAKE_ROOT], [1], [Define if you have the d_make_root function.])
    fi

    AC_CACHE_CHECK([whether struct dentry has a d_child member], [ac_cv_linuxmodule_dentry_d_child],
        [AC_LANG([C])
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([CLICK_LINUXMODULE_PROLOGUE()[
#include <linux/fs.h>
#include <linux/dcache.h>]],
[[extern struct dentry* de; de->d_child.next = 0;]])],
        [ac_cv_linuxmodule_dentry_d_child=yes], [ac_cv_linuxmodule_dentry_d_child=no])])
    if test $ac_cv_linuxmodule_dentry_d_child = yes; then
        AC_DEFINE([HAVE_LINUX_DENTRY_D_CHILD], [1], [Define if 'struct dentry' has a 'd_child' member.])
    fi

    fi dnl ac_cv_cxx_aware_system

    CC="$save_cc"
    CXX="$save_cxx"
    CPPFLAGS="$save_cppflags"
    CFLAGS="$save_cflags"
    CXXFLAGS="$save_cxxflags"
    export CFLAGS CPPFLAGS
fi


dnl check bsdmodule for BSD

if test $ac_have_bsd_kernel = y; then
    DRIVERS="$DRIVERS bsdmodule"
    if echo "$DRIVERS" | grep linuxmodule >/dev/null 2>&1; then :; else
        TOOL_TARGETS="$TOOL_TARGETS click-install"
    fi
    AC_DEFINE(HAVE_BSDMODULE_DRIVER)
    HAVE_BSDMODULE_DRIVER=1
fi


dnl check ns

if test "x$enable_nsclick" = xyes; then
    DRIVERS="$DRIVERS ns"
fi


dnl check minios

if test "x$enable_minios" = xyes; then
    DRIVERS="$DRIVERS minios"
    AC_DEFINE(HAVE_MINIOS_DRIVER)
    HAVE_MINIOS_DRIVER=1
fi

dnl check tools

if test "x$enable_tools" != xno; then
    OTHER_TARGETS="$OTHER_TARGETS tools"
fi


dnl
dnl programs needed for build process
dnl

CLICK_PROG_INSTALL
CLICK_PROG_GMAKE
CLICK_PROG_AUTOCONF
CLICK_PROG_PERL5
AC_PROG_AWK
AC_PROG_GREP
AC_PROG_EGREP
AC_CHECK_PROGS([MD5SUM], [md5sum md5])
AC_CHECK_PROGS([LLVMCONFIG], [llvm-config])


if test -z "$GMAKE"; then
    AC_MSG_ERROR([
==============================================

Can't find GNU make.  Either put 'gmake' on your PATH and
rerun './configure', or set the GMAKE environment variable to
GNU make's pathname.

==============================================])
fi

if test -z "$LLVMCONFIG" -o -n "${CXX##*clang*}" ; then
    have_llvm=no
else
    AC_DEFINE([HAVE_LLVM])
    have_llvm=yes
    LLVM_OBJS="llvmutils.o $LLVM_OBJS"
    LIBS_LLVM="`$LLVMCONFIG --ldflags --system-libs --libs all | tr -d '\n'` $LIBS_LLVM"
    INCLUDES_LLVM="`$LLVMCONFIG --cxxflags | tr -d '\n'` $INCLUDES_LLVM"
fi
AC_SUBST(LLVM_OBJS)
AC_SUBST(LIBS_LLVM)
AC_SUBST(INCLUDES_LLVM)

dnl
dnl install and clean versions of targets
dnl

AC_SUBST([INSTALL_TARGETS], [])
AC_SUBST([CLEAN_TARGETS], [])
for t in $DRIVERS $OTHER_TARGETS; do
    INSTALL_TARGETS="$INSTALL_TARGETS install-$t"
    CLEAN_TARGETS="$CLEAN_TARGETS clean-$t"
done

AC_SUBST([TOOL_INSTALL_TARGETS], [])
AC_SUBST([TOOL_CLEAN_TARGETS], [])
for t in $TOOL_TARGETS; do
    TOOL_INSTALL_TARGETS="$TOOL_INSTALL_TARGETS install-$t"
    TOOL_CLEAN_TARGETS="$TOOL_CLEAN_TARGETS clean-$t"
done


dnl
dnl Makeinfo, texi2dvi, install-info, pod2man
dnl

AC_MSG_CHECKING(for working makeinfo)
MAKEINFO=${MAKEINFO-makeinfo}
if ($MAKEINFO --version) < /dev/null > conftest.out 2>&1; then
    if test `head -n 1 conftest.out | sed 's/^.* \([[0-9]][[0-9]]*\).*$/\1/'` -ge 4; then
        AC_MSG_RESULT(found)
    else
        MAKEINFO='$(conf_auxdir)/missing makeinfo'
        AC_MSG_RESULT(old)
    fi
else
    MAKEINFO='$(conf_auxdir)/missing makeinfo'
    AC_MSG_RESULT(missing)
fi

AC_MSG_CHECKING(for working texi2dvi)
TEXI2DVI=${TEXI2DVI-texi2dvi}
if ($TEXI2DVI --version) < /dev/null > conftest.out 2>&1; then
    dnl Search for a good version of texi2dvi
    if test `head -n 1 conftest.out | sed 's/.*Texinfo \([[0-9]][[0-9]]*\).*/\1/'` -ge 4; then
        AC_MSG_RESULT(found)
    else
        TEXI2DVI='$(conf_auxdir)/missing texi2dvi'
        AC_MSG_RESULT(old)
    fi
else
    TEXI2DVI='$(conf_auxdir)/missing texi2dvi'
    AC_MSG_RESULT(missing)
fi

dnl Assume any version of install-info is OK
if test ${INSTALL_INFO-xxx} = xxx; then
    AC_PATH_PROG(INSTALL_INFO, install-info, '$(conf_auxdir)/missing install-info',
        $PATH:/sbin:/usr/sbin:/usr/local/sbin)
fi
AC_MSG_CHECKING(for working install-info)
if ($INSTALL_INFO --version) < /dev/null > conftest.out 2>&1; then
    AC_MSG_RESULT(found)
else
    INSTALL_INFO='$(conf_auxdir)/missing install-info'
    AC_MSG_RESULT(missing)
fi

AC_MSG_CHECKING(for working pod2man)
POD2MAN=${POD2MAN-pod2man}
if ($POD2MAN --help) < /dev/null > conftest.out 2>&1 && grep pod2man conftest.out >/dev/null 2>&1; then
    AC_MSG_RESULT(found)
else
    POD2MAN='$(conf_auxdir)/missing pod2man'
    AC_MSG_RESULT(missing)
fi


AC_SUBST(MAKEINFO)
AC_SUBST(TEXI2DVI)
AC_SUBST(INSTALL_INFO)
AC_SUBST(POD2MAN)


dnl
dnl substitute path variables
dnl

AC_DEFINE_UNQUOTED([CLICK_BINDIR], ["$bindir"], [Install directory for Click executables.])
AC_DEFINE_UNQUOTED([CLICK_LIBDIR], ["$libdir"], [Install directory for Click libraries and packages.])
AC_DEFINE_UNQUOTED([CLICK_DATADIR], ["$clickdatadir"], [Install directory for Click shared data.])

AC_DEFINE_UNQUOTED([CLICK_DIR], ["$clickdir"], [Source directory of Click.])

AC_SUBST(clickdatadir)
AC_SUBST(clickbuild_bindir)
AC_SUBST(clickbuild_clickdatadir)
AC_SUBST(clickbuild_datadir)
AC_SUBST(clickbuild_includedir)
AC_SUBST(clickbuild_libdir)
AC_SUBST(clickbuild_sbindir)
AC_SUBST(clickbuild_clickdir)


dnl
dnl Provisions
dnl

dnl start out with CPU
provisions="$target_cpu"
case "$target_cpu" in
    i386) :;;
    i486|i586) provisions="$provisions i386";;
    i686|i786) provisions="$provisions i386 i586";;
esac

dnl add 'analysis' if analysis elements are available
if test "x$enable_analysis" = xyes; then
    provisions="$provisions analysis"
fi

dnl add 'autobatch_jumplist' if autobatch is jump or list
if test "x$enable_auto_batch" == "xjump" -o "x$enable_auto_batch" == "xlist" ; then
    provisions="$provisions autobatch_jumplist"
fi

dnl add 'autobatch_port' if autobatch is port
if test "x$enable_auto_batch" == "xport" ; then
    provisions="$provisions autobatch_port"
fi

dnl add 'bpf' if BPF is found
if test "x$enable_bpf" = xyes; then
    provisions="$provisions bpf"
fi

dnl add 'batch' if compiled with --enable-batch
if test "x$enable_batch" = xyes; then
    provisions="$provisions batch"
else
    enable_batch="no"
fi

dnl add 'cxx17' if compiled a C++17 compiler
if test "x$ax_cv_cxx_compile_cxx17" = xyes; then
    provisions="$provisions cxx17"
fi

dnl add 'dpdk' if compiled with --enable-dpdk
if test "x$enable_dpdk" != "xno"; then
    provisions="$provisions dpdk"
    if test "$rte_ver_year" -ge 19; then
        provisions="$provisions dpdk19"
    fi
    if test "$rte_ver_year" -ge 18; then
        provisions="$provisions dpdk18"
    fi
    if test "$rte_ver_year" -ge 17; then
        provisions="$provisions dpdk17"
    fi
fi

dnl add 'dpdk-packet' if compiled with --enable-dpdk-packet
if test "x$enable_dpdk_packet" = xyes; then
    provisions="$provisions dpdk-packet"
    packet_mode="DPDK rte_mbuf"
else
    if test "x$enable_dpdk_pool" = xyes; then
        packet_mode="Click's Packet object with DPDK buffers in the pool"
    else
        packet_mode="Click's Packet object with any buffers"
    fi
fi

dnl add 'dpdk' if compiled with --enable-dpdk
if test "x$enable_dpdk_xchg" = xyes; then
    provisions="$provisions dpdk-xchg"
fi

dnl add 'flow' if compiled with --enable-flow
if test "x$enable_flow" = xyes; then
    provisions="$provisions flow"
    if test "x$enable_flow_dynamic" = xyes; then
        provisions="$provisions flow-dynamic"
    fi
else
    enable_flow="no"
fi

dnl add 'ctx', HAVE_CTX if compiled with --enable-ctx
if test "x$enable_ctx" = xyes; then
    provisions="$provisions ctx"
else
    enable_ctx="no"
fi

dnl add 'ctx-global-timeout', HAVE_CTX_GLOBAL_TIMEOUT if compiled with --enable-ctx-global-timeout
if test "x$enable_ctx_global_timeout" = xyes; then
    provisions="$provisions ctx-global-timeout"
fi



dnl add 'experimental' if --enable-experimental was supplied
if test "x$enable_experimental" = xyes; then
    provisions="$provisions experimental"
fi

dnl add 'tunnel' if tunnel elements are available
if test "x$enable_tunnel" = xyes; then
    provisions="$provisions tunnel"
fi

dnl add 'hs' if HyperScan lib is available
if test "x$have_hyperscan" = xyes; then
    provisions="$provisions hs"
fi

dnl add 'int64' if 64-bit integers are available
if test "x$have_int64_types" = xyes; then
    provisions="$provisions int64"
fi

dnl add 'ip6' if ip6 elements are available
if test "x$enable_ip6" = xyes; then
    provisions="$provisions ip6"
fi

dnl add 'linux' if compiling under linux
if test "x$ac_cv_under_linux" = xyes; then
    provisions="$provisions linux"
fi

dnl add provision for linux kernel version
if test $ac_have_linux_kernel = y; then
    if test $linux_version_code -ge 131584 -a $linux_version_code -lt 131840; then
        provisions="$provisions linux_2_2"
    elif test $linux_version_code -ge 132096 -a $linux_version_code -lt 132352; then
        provisions="$provisions linux_2_4"
    elif test $linux_version_code -ge 132608 -a $linux_version_code -lt 132864; then
        provisions="$provisions linux_2_6"
    fi
fi

dnl add 'load' if CPU load is tracked
if test "x$enable_cpu_load" = xyes; then
    provisions="$provisions load"
fi

dnl add 'mbglib' if mbglib support is available
if test "$ac_have_libmbdevio$ac_have_mbgdevio_h" = yesyes; then
    provisions="$provisions mbglib"
fi

dnl add 'microhttpd' if libmicrohttpd support is available
if test "$ac_have_libmicrohttpd$ac_have_microhttpd_h" = yesyes; then
    provisions="$provisions microhttpd"
fi

dnl add 'netmap' if netmap support is available
if test "x$HAVE_NETMAP" = xyes; then
    provisions="$provisions netmap"
fi

dnl add 'nonatimicfp' if compiled with --enable-fullpush-nonatomic
if test "x$enable_fullpush_nonatomic" = xyes; then
    provisions="$provisions nonatomicfp"
fi

dnl add 'numa' if numa support is available
if test "x$HAVE_NUMA" = xyes; then
    provisions="$provisions numa"
fi

dnl add 'papi' if libpapi support is available
if test "x$have_papi" = xyes; then
    provisions="$provisions papi"
fi

dnl add 'pcap' if libpcap is available
if test "x$HAVE_PCAP" = xyes; then
    provisions="$provisions pcap"
    have_pcap=yes
else
    have_pcap=no
fi

dnl add 'pci' if libpci support is available
if test "x$have_pci" = xyes; then
    provisions="$provisions pci"
fi

dnl add 'llvm' if llvm-config command is available
if test "x$have_llvm" = xyes; then
    provisions="$provisions llvm"
fi

dnl add 're2' if re2 is available
if test "x$have_re2" = xyes; then
    provisions="$provisions re2"
fi

dnl add 'rsspp' if RSS++ is available
if test "x$enable_rsspp" = xyes; then
    provisions="$provisions rsspp"
fi

dnl add 'smpclick' if compiled with --enable-multithread > 1
if test "$enable_multithread" != no; then
    provisions="$provisions smpclick"
fi

dnl add 'taskstats' if compiled with --enable-task-stats
if test "x$enable_task_stats" = xyes; then
    provisions="$provisions taskstats"
fi

dnl add 'umultithread' if compiled with --enable-user-multithread
if test "x$enable_user_multithread" = xyes; then
    provisions="$provisions umultithread"
fi

dnl add 'usertiming' if compiled with --enable-user-timestamp
if test "x$enable_user_timestamp" = xyes; then
    provisions="$provisions usertiming"
fi

dnl add 'wifi' if wifi elements are available
if test "x$enable_wifi" = xyes; then
    provisions="$provisions wifi"
fi

AC_SUBST(provisions)

dnl
dnl Output
dnl

test -f $srcdir/bsdmodule/Makefile.in && AC_CONFIG_FILES([bsdmodule/Makefile])
test -f $srcdir/linuxmodule/Makefile.in && AC_CONFIG_FILES([linuxmodule/Makefile])
test -f $srcdir/minios/Makefile.in && AC_CONFIG_FILES([minios/Makefile minios/config.mk])
test -f $srcdir/ns/Makefile.in && AC_CONFIG_FILES([ns/Makefile])
test -f $srcdir/userlevel/Makefile.in && AC_CONFIG_FILES([userlevel/Makefile])

test -f $srcdir/lib/json.cc && provisions="$provisions Json"

test -d $srcdir/tools/click-align && AC_CONFIG_FILES([tools/click-align/Makefile])
test -d $srcdir/tools/click-check && AC_CONFIG_FILES([tools/click-check/Makefile])
test -d $srcdir/tools/click-combine && AC_CONFIG_FILES([tools/click-combine/Makefile])
test -d $srcdir/tools/click-devirtualize && AC_CONFIG_FILES([tools/click-devirtualize/Makefile])
test -d $srcdir/tools/click-fastclassifier && AC_CONFIG_FILES([tools/click-fastclassifier/Makefile])
test -d $srcdir/tools/click-flatten && AC_CONFIG_FILES([tools/click-flatten/Makefile])
test -d $srcdir/tools/click-install && AC_CONFIG_FILES([tools/click-install/Makefile])
test -d $srcdir/tools/click-ipopt && AC_CONFIG_FILES([tools/click-ipopt/Makefile])
test -d $srcdir/tools/click-mkmindriver && AC_CONFIG_FILES([tools/click-mkmindriver/Makefile])
test -d $srcdir/tools/click-pretty && AC_CONFIG_FILES([tools/click-pretty/Makefile])
test -d $srcdir/tools/click-undead && AC_CONFIG_FILES([tools/click-undead/Makefile])
test -d $srcdir/tools/click-xform && AC_CONFIG_FILES([tools/click-xform/Makefile])
test -d $srcdir/tools/click2xml && AC_CONFIG_FILES([tools/click2xml/Makefile])

for ac_dir in bin etc include share share/click; do
    test ! -d "$ac_dir" && mkdir "$ac_dir"
done

AC_OUTPUT

feedback="no"

if test "$enable_flow_api$have_flow_api" = "yesno"; then
    feedback="To enable DPDK's Flow Rule Manager (rte_flow API), use a DPDK version >= 20.02."
fi

if test "x$enable_dpdk" != "xno"; then
    dpdk_info="${enable_dpdk}
    DPDK    Target:              ${RTE_TARGET}
    DPDK   Version:              ${RTE_VER_YEAR}.${RTE_VER_MONTH}
    DPDK      Path:              ${RTE_SDK}
    DPDK     build:              ${dpdk_sys}
    DPDK  Location:              ${RTE_LIB}"
else
    dpdk_info=${enable_dpdk}
fi

echo "

Configuration Summary:
    C     Compiler:              ${CC}
    C++   Compiler:              ${CXX}
    CFLAGS:                      ${CFLAGS}
    CXXFLAGS:                    ${CXXFLAGS}

          Batching:              ${enable_batch}
    Flow Subsystem:              ${enable_flow}
 Context Subsystem:              ${enable_ctx}
       HW Flow API:              ${have_flow_api}

    DPDK   support:              ${dpdk_info}

    RSS++  support:              ${enable_rsspp}

    Netmap support:              ${HAVE_NETMAP}
    PCAP   support:              ${have_pcap}

    PAPI   support:              ${have_papi}
    RE2    support:              ${have_re2}
    BPF    support:              ${have_libbpf}
    HTTPD  support:              ${have_httpd}
    libpci support:              ${have_pci}
    LLVM   support:              ${have_llvm}
"

if test "$feedback" != no; then
    echo ""
    echo $feedback
    echo ""
else
    echo "Now type make to build FastClick..."
fi
